diff --git a/.github/workflows/sonarqube.yaml b/.github/workflows/sonarqube.yaml new file mode 100644 index 0000000000..5d0ee1eef1 --- /dev/null +++ b/.github/workflows/sonarqube.yaml @@ -0,0 +1,55 @@ +name: SonarCloud +on: + workflow_dispatch: + pull_request: + types: [opened, synchronize, reopened] +jobs: + build: + name: Build and analyze + runs-on: ubuntu-latest + env: + SONAR_SCANNER_VERSION: 4.7.0.2747 + SONAR_SERVER_URL: "https://sonarcloud.io" + BUILD_WRAPPER_OUT_DIR: "$HOME/.sonar/build_wrapper_output" # Directory where build-wrapper output will be placed + FBT_NO_SYNC: "true" + TARGETS: f7 + DEFAULT_TARGET: f7 + steps: + - name: 'Decontaminate previous build leftovers' + run: | + if [ -d .git ]; then + git submodule status || git checkout "$(git rev-list --max-parents=0 HEAD | tail -n 1)" + fi + - uses: actions/checkout@v2 + with: + fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis + submodules: 'recursive' + - name: Set up JDK 11 + uses: actions/setup-java@v1 + with: + java-version: 11 + - name: Download and set up sonar-scanner + env: + SONAR_SCANNER_DOWNLOAD_URL: https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-${{ env.SONAR_SCANNER_VERSION }}-linux.zip + run: | + mkdir -p $HOME/.sonar + curl -sSLo $HOME/.sonar/sonar-scanner.zip ${{ env.SONAR_SCANNER_DOWNLOAD_URL }} + unzip -o $HOME/.sonar/sonar-scanner.zip -d $HOME/.sonar/ + echo "$HOME/.sonar/sonar-scanner-${{ env.SONAR_SCANNER_VERSION }}-linux/bin" >> $GITHUB_PATH + - name: Download and set up build-wrapper + env: + BUILD_WRAPPER_DOWNLOAD_URL: ${{ env.SONAR_SERVER_URL }}/static/cpp/build-wrapper-linux-x86.zip + run: | + curl -sSLo $HOME/.sonar/build-wrapper-linux-x86.zip ${{ env.BUILD_WRAPPER_DOWNLOAD_URL }} + unzip -o $HOME/.sonar/build-wrapper-linux-x86.zip -d $HOME/.sonar/ + echo "$HOME/.sonar/build-wrapper-linux-x86" >> $GITHUB_PATH + - name: Run build-wrapper + run: | + mkdir $HOME/.sonar/build_wrapper_output + build-wrapper-linux-x86-64 --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} ./sonar-build + - name: Run sonar-scanner + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + run: | + sonar-scanner --define sonar.host.url="${{ env.SONAR_SERVER_URL }}" --define sonar.cfamily.build-wrapper-output="${{ env.BUILD_WRAPPER_OUT_DIR }}" diff --git a/.gitignore b/.gitignore index 933b759a0a..6a3b80c65f 100644 --- a/.gitignore +++ b/.gitignore @@ -67,6 +67,8 @@ PVS-Studio.log # Automate files, etc automate.py deployments/ +assets/dolphin/custom/ +assets/resources/dolphin_custom/ fbt_options.py commitnotes.md lib/STM32CubeWB diff --git a/.pvsoptions b/.pvsoptions index 31bc4b8046..ca1b2b572a 100644 --- a/.pvsoptions +++ b/.pvsoptions @@ -1 +1 @@ ---rules-config .pvsconfig -e lib/fatfs -e lib/fnv1a-hash -e lib/FreeRTOS-Kernel -e lib/heatshrink -e lib/libusb_stm32 -e lib/littlefs -e lib/mbedtls -e lib/micro-ecc -e lib/microtar -e lib/mlib -e lib/qrcode -e lib/ST25RFAL002 -e lib/STM32CubeWB -e lib/u8g2 -e lib/nanopb -e */arm-none-eabi/* -e applications/plugins/dap_link/lib/free-dap +--ignore-ccache -C gccarm --rules-config .pvsconfig -e lib/fatfs -e lib/fnv1a-hash -e lib/FreeRTOS-Kernel -e lib/heatshrink -e lib/libusb_stm32 -e lib/littlefs -e lib/mbedtls -e lib/micro-ecc -e lib/microtar -e lib/mlib -e lib/qrcode -e lib/ST25RFAL002 -e lib/STM32CubeWB -e lib/u8g2 -e lib/nanopb -e */arm-none-eabi/* -e applications/plugins/dap_link/lib/free-dap diff --git a/.vscode/example/tasks.json b/.vscode/example/tasks.json index 0fc1d6dd1b..f2522668d4 100644 --- a/.vscode/example/tasks.json +++ b/.vscode/example/tasks.json @@ -105,6 +105,12 @@ "type": "shell", "command": "./fbt COMPACT=1 DEBUG=0 FORCE=1 flash_usb_full" }, + { + "label": "[Debug] Create PVS-Studio report", + "group": "build", + "type": "shell", + "command": "./fbt firmware_pvs" + }, { "label": "[Debug] Build FAPs", "group": "build", diff --git a/ReadMe.md b/ReadMe.md index fdd4b3bf04..f8c94a7fce 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -4,7 +4,7 @@

-[Intro](https://github.com/ClaraCrazy/Flipper-Xtreme#What-makes-it-special) | [Animations](https://github.com/ClaraCrazy/Flipper-Xtreme#Animations) | [Docs](https://github.com/ClaraCrazy/Flipper-Xtreme/wiki) | [Changelog](https://github.com/ClaraCrazy/Flipper-Xtreme#list-of-changes) | [Known bugs](https://github.com/ClaraCrazy/Flipper-Xtreme#Known-bugs) | [Install](https://github.com/ClaraCrazy/Flipper-Xtreme#Install) | [Build](https://github.com/ClaraCrazy/Flipper-Xtreme#build-it-yourself) | [Discord](https://discord.gg/flipper-xtreme) +[Intro](https://github.com/ClaraCrazy/Flipper-Xtreme#What-makes-it-special) | [Animations](https://github.com/ClaraCrazy/Flipper-Xtreme#Animations--Asset-Packs) | [Docs](https://github.com/ClaraCrazy/Flipper-Xtreme/wiki) | [Changelog](https://github.com/ClaraCrazy/Flipper-Xtreme#list-of-changes) | [Known bugs](https://github.com/ClaraCrazy/Flipper-Xtreme#Known-bugs) | [Install](https://github.com/ClaraCrazy/Flipper-Xtreme#Install) | [Build](https://github.com/ClaraCrazy/Flipper-Xtreme#build-it-yourself) | [Discord](https://discord.gg/flipper-xtreme) ----- This firmware is a complete overhaul of the [Official Firmware](https://github.com/flipperdevices/flipperzero-firmware), it also features some of the badly implemented ideas from RogueMaster, and lots of awesome code-bits from [Unleashed](https://github.com/DarkFlippers/unleashed-firmware). @@ -28,11 +28,33 @@ The goal of this Firmware is to regularly bring out amazing updates based on wha -----
-

Animations:

+

Animations / Asset Packs:

-This firmware contains NSFW animations and uses these in stock (NSFW) mode. +We created our own, new & improved Animation / Asset system, that we can finally reveal. It lets you to create and cycle through your own `Asset Packs` with only a few button presses, allowing you to easily load custom Animations and Icons like never before. -The animations are tied to the level system. Each level you reach, unlocks a new animation. The higher your level, the more lewd it will become. Rumors have it, I'm to be found in at least one of those too + +You can easily create your own pack, or find some user made ones in the discord channel. Check here for a tutorial on creating your own. Essentially, we got our own Anims & Icons folders, inside each Asset Pack. + +
+ + +Once you have some packs, upload them to your Flipper in SD/dolphin_custom (if you did this right you should see SD/dolphin_custom/PackName/Anims and/or SD/dolphin_custom/PackName/Icons). + + +
+ + +After installing the packs to Flipper, hit the Arrow UP button on the main menu and go to Xtreme Settings. Here choose which pack you want and tweak the other settings how you prefer, then press back to reboot and enjoy your new assets & animations! + +
+ +----- +
+

Levels:

+ +This firmware contains some NSFW animations to bring a twist to the boring community, and added a fun leveling-system around them, that you can easily add to your own `Asset Packs`. + +The idle_animations are tied to the level system. Each level you reach, unlocks a new animation. The higher your level, the more lewd it will become. Rumors have it, I'm to be found in at least one of those too | Level | Animations | | ------------- | ------------- | @@ -40,7 +62,7 @@ The animations are tied to the level system. Each level you reach, unlocks a new | 11-20 | Some tits, maybe an ass | | 21-30 | Fully NSFW, graphic scenes | -If you dont like that, we added an SFW mode to the Firmware. From the main menu, hit `Arrow UP` and select SFW mode and now all assets will be stock. +By default, SFW mode is selected, but if you want to enable all of the above simply hit `Arrow UP` from the main menu, select `Xtreme Settings` and change to NSFW graphics. -----
@@ -51,30 +73,31 @@ Note: This repo is always updated with OFW & Unleashed. No need to mention all t ```txt [Added] -- SFW Mode +- Xtreme App +- Asset Packs +- More UI options +- A new battery display-type +- Scrolling view for long file names in browser +- NSFW Animations tied to the level system. Read more above +- Folder handling for empty ones (Now indicate they are empty) + - Jamming Files - Custom subghz presets -- Added new Battery display-type +- Multiple NFC protocols - Subghz and IR signal replication via gpio | Credits to @ankris812 - Honda Keys (CVE-2022-27254) & Ford blockers -- NSFW Animations tied to the level system. Read more above + - New API Routes for Locale settings -- Scrolling view for long file names in browser -- Tamagotchi rom ``` ```txt [Updated] -- All graphics +- All Assets + +- Tons of apps +- Massive compiler re-do - About 1k files to speed things up a lot -- Folder handling for empty ones (Now indicate they are empty) -- Applications now use the new Locale setting -- Compiler now handles all non-compiled faps during build -- Compiler now accepts WIP SDK -- Compiler just stfu about non-fatal problems -- Some further NFC stuff -- Weather App -- Applications now use above mentioned API Routes +- Applications to now use the new Locale setting ``` ```txt [Fixed] @@ -89,7 +112,7 @@ Note: This repo is always updated with OFW & Unleashed. No need to mention all t - Unused Dummy Mode - Broken apps (bad apple, chess, etc.) -- Unused code from FAPs and system calls +- Tons of unused code from FAPs and system calls ``` ---- diff --git a/SConstruct b/SConstruct index b8c65044d0..62e37dfdcb 100644 --- a/SConstruct +++ b/SConstruct @@ -148,9 +148,12 @@ fap_dist = [ for app_artifact in firmware_env["FW_EXTAPPS"].applications.values() ), ), - distenv.Install( - f"#/dist/{dist_dir}/apps", - "#/assets/resources/apps", + *( + distenv.Install( + f"#/dist/{dist_dir}/apps/{app_artifact.app.fap_category}", + app_artifact.compact[0], + ) + for app_artifact in firmware_env["FW_EXTAPPS"].applications.values() ), ] Depends( diff --git a/applications/debug/accessor/accessor_app.cpp b/applications/debug/accessor/accessor_app.cpp index 2e3e27ec45..9d3708ebeb 100644 --- a/applications/debug/accessor/accessor_app.cpp +++ b/applications/debug/accessor/accessor_app.cpp @@ -31,7 +31,8 @@ void AccessorApp::run(void) { onewire_host_stop(onewire_host); } -AccessorApp::AccessorApp() { +AccessorApp::AccessorApp() + : text_store{0} { notification = static_cast(furi_record_open(RECORD_NOTIFICATION)); onewire_host = onewire_host_alloc(); furi_hal_power_enable_otg(); diff --git a/applications/debug/accessor/helpers/wiegand.cpp b/applications/debug/accessor/helpers/wiegand.cpp index bb28855499..5cb3a85f58 100644 --- a/applications/debug/accessor/helpers/wiegand.cpp +++ b/applications/debug/accessor/helpers/wiegand.cpp @@ -171,9 +171,6 @@ bool WIEGAND::DoWiegandConversion() { return true; } else { _lastWiegand = sysTick; - _bitCount = 0; - _cardTemp = 0; - _cardTempHigh = 0; return false; } diff --git a/applications/debug/bt_debug_app/views/bt_test.c b/applications/debug/bt_debug_app/views/bt_test.c index 9588b667b6..cd52b8650e 100644 --- a/applications/debug/bt_debug_app/views/bt_test.c +++ b/applications/debug/bt_debug_app/views/bt_test.c @@ -2,8 +2,11 @@ #include #include + +#include #include #include +#include #include struct BtTestParam { @@ -98,16 +101,16 @@ static void bt_test_draw_callback(Canvas* canvas, void* _model) { elements_scrollbar(canvas, model->position, BtTestParamArray_size(model->params)); canvas_draw_str(canvas, 6, 60, model->message); if(model->state == BtTestStateStarted) { - if(model->rssi != 0.0f) { + if(!float_is_equal(model->rssi, 0.0f)) { snprintf(info_str, sizeof(info_str), "RSSI:%3.1f dB", (double)model->rssi); canvas_draw_str_aligned(canvas, 124, 60, AlignRight, AlignBottom, info_str); } } else if(model->state == BtTestStateStopped) { if(model->packets_num_rx) { - snprintf(info_str, sizeof(info_str), "%ld pack rcv", model->packets_num_rx); + snprintf(info_str, sizeof(info_str), "%" PRIu32 " pack rcv", model->packets_num_rx); canvas_draw_str_aligned(canvas, 124, 60, AlignRight, AlignBottom, info_str); } else if(model->packets_num_tx) { - snprintf(info_str, sizeof(info_str), "%ld pack sent", model->packets_num_tx); + snprintf(info_str, sizeof(info_str), "%" PRIu32 " pack sent", model->packets_num_tx); canvas_draw_str_aligned(canvas, 124, 60, AlignRight, AlignBottom, info_str); } } @@ -153,7 +156,7 @@ static bool bt_test_input_callback(InputEvent* event, void* context) { } void bt_test_process_up(BtTest* bt_test) { - with_view_model( + with_view_model( // -V658 bt_test->view, BtTestModel * model, { diff --git a/applications/debug/file_browser_test/file_browser_app.c b/applications/debug/file_browser_test/file_browser_app.c index 996cb2bd24..bf423d34ed 100644 --- a/applications/debug/file_browser_test/file_browser_app.c +++ b/applications/debug/file_browser_test/file_browser_app.c @@ -48,7 +48,7 @@ FileBrowserApp* file_browser_app_alloc(char* arg) { app->file_path = furi_string_alloc(); app->file_browser = file_browser_alloc(app->file_path); - file_browser_configure(app->file_browser, "*", NULL, true, &I_badusb_10px, true); + file_browser_configure(app->file_browser, "*", NULL, true, false, &I_badusb_10px, true); view_dispatcher_add_view( app->view_dispatcher, FileBrowserAppViewStart, widget_get_view(app->widget)); diff --git a/applications/examples/application.fam b/applications/examples/application.fam index 16d240ccf4..8556714c90 100644 --- a/applications/examples/application.fam +++ b/applications/examples/application.fam @@ -1,5 +1,5 @@ App( - appid="sample_apps", - name="Sample apps bundle", + appid="example_apps", + name="Example apps bundle", apptype=FlipperAppType.METAPACKAGE, ) diff --git a/applications/main/bad_usb/scenes/bad_usb_scene_error.c b/applications/main/bad_usb/scenes/bad_usb_scene_error.c index 8a50a2df85..2c707bbf16 100644 --- a/applications/main/bad_usb/scenes/bad_usb_scene_error.c +++ b/applications/main/bad_usb/scenes/bad_usb_scene_error.c @@ -1,5 +1,5 @@ #include "../bad_usb_app_i.h" -#include "../../../settings/desktop_settings/desktop_settings_app.h" +#include "../../../settings/xtreme_settings/xtreme_settings.h" typedef enum { BadUsbCustomEventErrorBack, @@ -17,8 +17,6 @@ static void void bad_usb_scene_error_on_enter(void* context) { BadUsbApp* app = context; - DesktopSettings* settings = malloc(sizeof(DesktopSettings)); - DESKTOP_SETTINGS_LOAD(settings); if(app->error == BadUsbAppErrorNoFiles) { widget_add_icon_element(app->widget, 0, 0, &I_SDQuestion_35x43); @@ -34,9 +32,9 @@ void bad_usb_scene_error_on_enter(void* context) { app->widget, GuiButtonTypeLeft, "Back", bad_usb_scene_error_event_callback, app); } else if(app->error == BadUsbAppErrorCloseRpc) { widget_add_icon_element(app->widget, 78, 0, &I_ActiveConnection_50x64); - if(settings->sfw_mode) { + if(XTREME_SETTINGS()->nsfw_mode) { widget_add_string_multiline_element( - app->widget, 3, 2, AlignLeft, AlignTop, FontPrimary, "Connection\nis active!"); + app->widget, 3, 2, AlignLeft, AlignTop, FontPrimary, "I am not\na whore!"); widget_add_string_multiline_element( app->widget, 3, @@ -44,10 +42,10 @@ void bad_usb_scene_error_on_enter(void* context) { AlignLeft, AlignTop, FontSecondary, - "Disconnect from\nPC or phone to\nuse this function."); + "Pull out from\nPC or phone to\nuse me like this."); } else { widget_add_string_multiline_element( - app->widget, 3, 2, AlignLeft, AlignTop, FontPrimary, "I am not\na whore!"); + app->widget, 3, 2, AlignLeft, AlignTop, FontPrimary, "Connection\nis active!"); widget_add_string_multiline_element( app->widget, 3, @@ -55,12 +53,11 @@ void bad_usb_scene_error_on_enter(void* context) { AlignLeft, AlignTop, FontSecondary, - "Pull out from\nPC or phone to\nuse me like this."); + "Disconnect from\nPC or phone to\nuse this function."); } } view_dispatcher_switch_to_view(app->view_dispatcher, BadUsbAppViewError); - free(settings); } bool bad_usb_scene_error_on_event(void* context, SceneManagerEvent event) { diff --git a/applications/main/bad_usb/views/bad_usb_view.c b/applications/main/bad_usb/views/bad_usb_view.c index b700bc0236..ad889cd1c9 100644 --- a/applications/main/bad_usb/views/bad_usb_view.c +++ b/applications/main/bad_usb/views/bad_usb_view.c @@ -3,7 +3,7 @@ #include #include #include -#include "../../../settings/desktop_settings/desktop_settings_app.h" +#include "../../../settings/xtreme_settings/xtreme_settings.h" #define MAX_NAME_LEN 64 @@ -28,8 +28,7 @@ static void bad_usb_draw_callback(Canvas* canvas, void* _model) { elements_string_fit_width(canvas, disp_str, 128 - 2); canvas_set_font(canvas, FontSecondary); canvas_draw_str(canvas, 2, 8, furi_string_get_cstr(disp_str)); - DesktopSettings* settings = malloc(sizeof(DesktopSettings)); - DESKTOP_SETTINGS_LOAD(settings); + XtremeSettings* xtreme_settings = XTREME_SETTINGS(); if(strlen(model->layout) == 0) { furi_string_set(disp_str, "(default)"); @@ -50,10 +49,10 @@ static void bad_usb_draw_callback(Canvas* canvas, void* _model) { if((model->state.state == BadUsbStateIdle) || (model->state.state == BadUsbStateDone) || (model->state.state == BadUsbStateNotConnected)) { - if(settings->sfw_mode) { - elements_button_center(canvas, "Start"); - } else { + if(xtreme_settings->nsfw_mode) { elements_button_center(canvas, "Cum"); + } else { + elements_button_center(canvas, "Start"); } } else if((model->state.state == BadUsbStateRunning) || (model->state.state == BadUsbStateDelay)) { elements_button_center(canvas, "Stop"); @@ -69,20 +68,20 @@ static void bad_usb_draw_callback(Canvas* canvas, void* _model) { if(model->state.state == BadUsbStateNotConnected) { canvas_draw_icon(canvas, 4, 26, &I_Clock_18x18); canvas_set_font(canvas, FontPrimary); - if(settings->sfw_mode) { - canvas_draw_str_aligned(canvas, 127, 31, AlignRight, AlignBottom, "Connect to"); - canvas_draw_str_aligned(canvas, 127, 43, AlignRight, AlignBottom, "a device"); - } else { + if(xtreme_settings->nsfw_mode) { canvas_draw_str_aligned(canvas, 127, 31, AlignRight, AlignBottom, "Plug me"); canvas_draw_str_aligned(canvas, 127, 43, AlignRight, AlignBottom, "in, Daddy"); + } else { + canvas_draw_str_aligned(canvas, 127, 31, AlignRight, AlignBottom, "Connect to"); + canvas_draw_str_aligned(canvas, 127, 43, AlignRight, AlignBottom, "a device"); } } else if(model->state.state == BadUsbStateWillRun) { canvas_draw_icon(canvas, 4, 26, &I_Clock_18x18); canvas_set_font(canvas, FontPrimary); - if(settings->sfw_mode) { - canvas_draw_str_aligned(canvas, 127, 31, AlignRight, AlignBottom, "Will run"); - } else { + if(xtreme_settings->nsfw_mode) { canvas_draw_str_aligned(canvas, 127, 31, AlignRight, AlignBottom, "Will cum"); + } else { + canvas_draw_str_aligned(canvas, 127, 31, AlignRight, AlignBottom, "Will run"); } canvas_draw_str_aligned(canvas, 127, 43, AlignRight, AlignBottom, "on connect"); } else if(model->state.state == BadUsbStateFileError) { @@ -147,7 +146,6 @@ static void bad_usb_draw_callback(Canvas* canvas, void* _model) { } furi_string_free(disp_str); - free(settings); } static bool bad_usb_input_callback(InputEvent* event, void* context) { diff --git a/applications/main/ibutton/scenes/ibutton_scene_delete_success.c b/applications/main/ibutton/scenes/ibutton_scene_delete_success.c index f543ceeb2d..5f12d49d7e 100644 --- a/applications/main/ibutton/scenes/ibutton_scene_delete_success.c +++ b/applications/main/ibutton/scenes/ibutton_scene_delete_success.c @@ -1,5 +1,5 @@ #include "../ibutton_i.h" -#include "../../../settings/desktop_settings/desktop_settings_app.h" +#include "../../../settings/xtreme_settings/xtreme_assets.h" static void ibutton_scene_delete_success_popup_callback(void* context) { iButton* ibutton = context; @@ -9,14 +9,8 @@ static void ibutton_scene_delete_success_popup_callback(void* context) { void ibutton_scene_delete_success_on_enter(void* context) { iButton* ibutton = context; Popup* popup = ibutton->popup; - DesktopSettings* settings = malloc(sizeof(DesktopSettings)); - DESKTOP_SETTINGS_LOAD(settings); - if(settings->sfw_mode) { - popup_set_icon(popup, 0, 2, &I_DolphinMafia_115x62_sfw); - } else { - popup_set_icon(popup, 0, 2, &I_DolphinMafia_115x62); - } + popup_set_icon(popup, 0, 2, XTREME_ASSETS()->I_DolphinMafia_115x62); popup_set_header(popup, "Deleted", 83, 19, AlignLeft, AlignBottom); popup_set_callback(popup, ibutton_scene_delete_success_popup_callback); @@ -25,7 +19,6 @@ void ibutton_scene_delete_success_on_enter(void* context) { popup_enable_timeout(popup); view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewPopup); - free(settings); } bool ibutton_scene_delete_success_on_event(void* context, SceneManagerEvent event) { diff --git a/applications/main/ibutton/scenes/ibutton_scene_read.c b/applications/main/ibutton/scenes/ibutton_scene_read.c index 4dbbed3521..718cb8bfc1 100644 --- a/applications/main/ibutton/scenes/ibutton_scene_read.c +++ b/applications/main/ibutton/scenes/ibutton_scene_read.c @@ -1,6 +1,6 @@ #include "../ibutton_i.h" #include -#include "../../../settings/desktop_settings/desktop_settings_app.h" +#include "../../../settings/xtreme_settings/xtreme_assets.h" static void ibutton_scene_read_callback(void* context) { iButton* ibutton = context; @@ -12,16 +12,10 @@ void ibutton_scene_read_on_enter(void* context) { Popup* popup = ibutton->popup; iButtonKey* key = ibutton->key; iButtonWorker* worker = ibutton->key_worker; - DesktopSettings* settings = malloc(sizeof(DesktopSettings)); - DESKTOP_SETTINGS_LOAD(settings); popup_set_header(popup, "iButton", 95, 26, AlignCenter, AlignBottom); popup_set_text(popup, "Waiting\nfor key ...", 95, 30, AlignCenter, AlignTop); - if(settings->sfw_mode) { - popup_set_icon(popup, 0, 5, &I_DolphinWait_61x59_sfw); - } else { - popup_set_icon(popup, 0, 5, &I_DolphinWait_61x59); - } + popup_set_icon(popup, 0, 5, XTREME_ASSETS()->I_DolphinWait_61x59); view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewPopup); furi_string_set(ibutton->file_path, IBUTTON_APP_FOLDER); @@ -30,7 +24,6 @@ void ibutton_scene_read_on_enter(void* context) { ibutton_worker_read_start(worker, key); ibutton_notification_message(ibutton, iButtonNotificationMessageReadStart); - free(settings); } bool ibutton_scene_read_on_event(void* context, SceneManagerEvent event) { diff --git a/applications/main/ibutton/scenes/ibutton_scene_save_success.c b/applications/main/ibutton/scenes/ibutton_scene_save_success.c index 02c6abe2ba..ee49b432c7 100644 --- a/applications/main/ibutton/scenes/ibutton_scene_save_success.c +++ b/applications/main/ibutton/scenes/ibutton_scene_save_success.c @@ -1,5 +1,5 @@ #include "../ibutton_i.h" -#include "../../../settings/desktop_settings/desktop_settings_app.h" +#include "../../../settings/xtreme_settings/xtreme_assets.h" static void ibutton_scene_save_success_popup_callback(void* context) { iButton* ibutton = context; @@ -9,14 +9,8 @@ static void ibutton_scene_save_success_popup_callback(void* context) { void ibutton_scene_save_success_on_enter(void* context) { iButton* ibutton = context; Popup* popup = ibutton->popup; - DesktopSettings* settings = malloc(sizeof(DesktopSettings)); - DESKTOP_SETTINGS_LOAD(settings); - if(settings->sfw_mode) { - popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59_sfw); - } else { - popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59); - } + popup_set_icon(popup, 32, 5, XTREME_ASSETS()->I_DolphinNice_96x59); popup_set_header(popup, "Saved!", 5, 7, AlignLeft, AlignTop); popup_set_callback(popup, ibutton_scene_save_success_popup_callback); @@ -25,7 +19,6 @@ void ibutton_scene_save_success_on_enter(void* context) { popup_enable_timeout(popup); view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewPopup); - free(settings); } bool ibutton_scene_save_success_on_event(void* context, SceneManagerEvent event) { diff --git a/applications/main/ibutton/scenes/ibutton_scene_write_success.c b/applications/main/ibutton/scenes/ibutton_scene_write_success.c index 3d461018cb..e77f3f0499 100644 --- a/applications/main/ibutton/scenes/ibutton_scene_write_success.c +++ b/applications/main/ibutton/scenes/ibutton_scene_write_success.c @@ -1,5 +1,5 @@ #include "../ibutton_i.h" -#include "../../../settings/desktop_settings/desktop_settings_app.h" +#include "../../../settings/xtreme_settings/xtreme_assets.h" static void ibutton_scene_write_success_popup_callback(void* context) { iButton* ibutton = context; @@ -10,14 +10,8 @@ static void ibutton_scene_write_success_popup_callback(void* context) { void ibutton_scene_write_success_on_enter(void* context) { iButton* ibutton = context; Popup* popup = ibutton->popup; - DesktopSettings* settings = malloc(sizeof(DesktopSettings)); - DESKTOP_SETTINGS_LOAD(settings); - if(settings->sfw_mode) { - popup_set_icon(popup, 0, 12, &I_iButtonDolphinVerySuccess_108x52_sfw); - } else { - popup_set_icon(popup, 0, 12, &I_iButtonDolphinVerySuccess_108x52); - } + popup_set_icon(popup, 0, 12, XTREME_ASSETS()->I_iButtonDolphinVerySuccess_108x52); popup_set_text(popup, "Successfully written!", 40, 12, AlignLeft, AlignBottom); popup_set_callback(popup, ibutton_scene_write_success_popup_callback); @@ -28,7 +22,6 @@ void ibutton_scene_write_success_on_enter(void* context) { view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewPopup); ibutton_notification_message(ibutton, iButtonNotificationMessageSuccess); ibutton_notification_message(ibutton, iButtonNotificationMessageGreenOn); - free(settings); } bool ibutton_scene_write_success_on_event(void* context, SceneManagerEvent event) { diff --git a/applications/main/infrared/scenes/infrared_scene_edit_rename_done.c b/applications/main/infrared/scenes/infrared_scene_edit_rename_done.c index 056c97db6a..3d7a9d0814 100644 --- a/applications/main/infrared/scenes/infrared_scene_edit_rename_done.c +++ b/applications/main/infrared/scenes/infrared_scene_edit_rename_done.c @@ -1,17 +1,11 @@ #include "../infrared_i.h" -#include "../../../settings/desktop_settings/desktop_settings_app.h" +#include "../../../settings/xtreme_settings/xtreme_assets.h" void infrared_scene_edit_rename_done_on_enter(void* context) { Infrared* infrared = context; Popup* popup = infrared->popup; - DesktopSettings* settings = malloc(sizeof(DesktopSettings)); - DESKTOP_SETTINGS_LOAD(settings); - if(settings->sfw_mode) { - popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59_sfw); - } else { - popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59); - } + popup_set_icon(popup, 32, 5, XTREME_ASSETS()->I_DolphinNice_96x59); popup_set_header(popup, "Saved!", 5, 7, AlignLeft, AlignTop); popup_set_callback(popup, infrared_popup_closed_callback); @@ -20,7 +14,6 @@ void infrared_scene_edit_rename_done_on_enter(void* context) { popup_enable_timeout(popup); view_dispatcher_switch_to_view(infrared->view_dispatcher, InfraredViewPopup); - free(settings); } bool infrared_scene_edit_rename_done_on_event(void* context, SceneManagerEvent event) { diff --git a/applications/main/infrared/scenes/infrared_scene_learn_done.c b/applications/main/infrared/scenes/infrared_scene_learn_done.c index a66445efe0..dce74db542 100644 --- a/applications/main/infrared/scenes/infrared_scene_learn_done.c +++ b/applications/main/infrared/scenes/infrared_scene_learn_done.c @@ -1,21 +1,15 @@ #include "../infrared_i.h" -#include "../../../settings/desktop_settings/desktop_settings_app.h" +#include "../../../settings/xtreme_settings/xtreme_assets.h" void infrared_scene_learn_done_on_enter(void* context) { Infrared* infrared = context; Popup* popup = infrared->popup; - DesktopSettings* settings = malloc(sizeof(DesktopSettings)); - DESKTOP_SETTINGS_LOAD(settings); - - if(settings->sfw_mode) { - popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59_sfw); - if(infrared->app_state.is_learning_new_remote) { - popup_set_header(popup, "New remote\ncreated!", 0, 0, AlignLeft, AlignTop); - } else { - popup_set_header(popup, "Saved!", 5, 7, AlignLeft, AlignTop); - } + + popup_set_icon(popup, 32, 5, XTREME_ASSETS()->I_DolphinNice_96x59); + if(infrared->app_state.is_learning_new_remote) { + popup_set_header(popup, "New remote\ncreated!", 0, 0, AlignLeft, AlignTop); } else { - popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59); + popup_set_header(popup, "Saved!", 5, 7, AlignLeft, AlignTop); } popup_set_callback(popup, infrared_popup_closed_callback); @@ -24,7 +18,6 @@ void infrared_scene_learn_done_on_enter(void* context) { popup_enable_timeout(popup); view_dispatcher_switch_to_view(infrared->view_dispatcher, InfraredViewPopup); - free(settings); } bool infrared_scene_learn_done_on_event(void* context, SceneManagerEvent event) { diff --git a/applications/main/infrared/scenes/infrared_scene_learn_success.c b/applications/main/infrared/scenes/infrared_scene_learn_success.c index 82ced17c2e..3340a63425 100644 --- a/applications/main/infrared/scenes/infrared_scene_learn_success.c +++ b/applications/main/infrared/scenes/infrared_scene_learn_success.c @@ -1,5 +1,5 @@ #include "../infrared_i.h" -#include "../../../settings/desktop_settings/desktop_settings_app.h" +#include "../../../settings/xtreme_settings/xtreme_assets.h" static void infrared_scene_learn_success_dialog_result_callback(DialogExResult result, void* context) { @@ -11,8 +11,6 @@ void infrared_scene_learn_success_on_enter(void* context) { Infrared* infrared = context; DialogEx* dialog_ex = infrared->dialog_ex; InfraredSignal* signal = infrared->received_signal; - DesktopSettings* settings = malloc(sizeof(DesktopSettings)); - DESKTOP_SETTINGS_LOAD(settings); infrared_play_notification_message(infrared, InfraredNotificationMessageGreenOn); @@ -50,17 +48,12 @@ void infrared_scene_learn_success_on_enter(void* context) { dialog_ex_set_left_button_text(dialog_ex, "Retry"); dialog_ex_set_right_button_text(dialog_ex, "Save"); dialog_ex_set_center_button_text(dialog_ex, "Send"); - if(settings->sfw_mode) { - dialog_ex_set_icon(dialog_ex, 0, 1, &I_DolphinReadingSuccess_59x63_sfw); - } else { - dialog_ex_set_icon(dialog_ex, 0, 1, &I_DolphinReadingSuccess_59x63); - } + dialog_ex_set_icon(dialog_ex, 0, 1, XTREME_ASSETS()->I_DolphinReadingSuccess_59x63); dialog_ex_set_result_callback(dialog_ex, infrared_scene_learn_success_dialog_result_callback); dialog_ex_set_context(dialog_ex, context); dialog_ex_enable_extended_events(dialog_ex); view_dispatcher_switch_to_view(infrared->view_dispatcher, InfraredViewDialogEx); - free(settings); } bool infrared_scene_learn_success_on_event(void* context, SceneManagerEvent event) { diff --git a/applications/main/lfrfid/scenes/lfrfid_scene_clear_t5577.c b/applications/main/lfrfid/scenes/lfrfid_scene_clear_t5577.c index 565655080c..7d9d507658 100644 --- a/applications/main/lfrfid/scenes/lfrfid_scene_clear_t5577.c +++ b/applications/main/lfrfid/scenes/lfrfid_scene_clear_t5577.c @@ -1,6 +1,6 @@ #include "../lfrfid_i.h" #include "../helpers/rfid_writer.h" -#include "../../../settings/desktop_settings/desktop_settings_app.h" +#include "../../../settings/xtreme_settings/xtreme_assets.h" static void writer_initialize(T55xxTiming* t55xxtiming) { t55xxtiming->wait_time = 400; @@ -15,8 +15,6 @@ static void lfrfid_clear_t5577_password_and_config_to_EM(LfRfid* app) { T55xxTiming* t55xxtiming = malloc(sizeof(T55xxTiming)); Popup* popup = app->popup; char curr_buf[32] = {}; - DesktopSettings* settings = malloc(sizeof(DesktopSettings)); - DESKTOP_SETTINGS_LOAD(settings); //TODO: use .txt file in resourses for passwords. const uint32_t default_passwords[] = { @@ -45,11 +43,7 @@ static void lfrfid_clear_t5577_password_and_config_to_EM(LfRfid* app) { writer_initialize(t55xxtiming); popup_set_header(popup, "Removing\npassword", 90, 36, AlignCenter, AlignCenter); - if(settings->sfw_mode) { - popup_set_icon(popup, 0, 3, &I_RFIDDolphinSend_97x61_sfw); - } else { - popup_set_icon(popup, 0, 3, &I_RFIDDolphinSend_97x61); - } + popup_set_icon(popup, 0, 3, XTREME_ASSETS()->I_RFIDDolphinSend_97x61); popup_set_text(popup, curr_buf, 90, 56, AlignCenter, AlignCenter); notification_message(app->notifications, &sequence_blink_start_magenta); @@ -67,24 +61,17 @@ static void lfrfid_clear_t5577_password_and_config_to_EM(LfRfid* app) { notification_message(app->notifications, &sequence_blink_stop); popup_reset(app->popup); free(t55xxtiming); - free(settings); } void lfrfid_scene_clear_t5577_on_enter(void* context) { LfRfid* app = context; Popup* popup = app->popup; - DesktopSettings* settings = malloc(sizeof(DesktopSettings)); - DESKTOP_SETTINGS_LOAD(settings); lfrfid_clear_t5577_password_and_config_to_EM(app); notification_message(app->notifications, &sequence_success); popup_set_header(popup, "Done!", 94, 10, AlignCenter, AlignTop); - if(settings->sfw_mode) { - popup_set_icon(popup, 0, 7, &I_RFIDDolphinSuccess_108x57_sfw); - } else { - popup_set_icon(popup, 0, 7, &I_RFIDDolphinSuccess_108x57); - } + popup_set_icon(popup, 0, 7, XTREME_ASSETS()->I_RFIDDolphinSuccess_108x57); popup_set_context(popup, app); popup_set_callback(popup, lfrfid_popup_timeout_callback); popup_set_timeout(popup, 1500); @@ -92,7 +79,6 @@ void lfrfid_scene_clear_t5577_on_enter(void* context) { view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidViewPopup); notification_message_block(app->notifications, &sequence_set_green_255); - free(settings); } bool lfrfid_scene_clear_t5577_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 94e5a684ef..873382b6c4 100644 --- a/applications/main/lfrfid/scenes/lfrfid_scene_delete_success.c +++ b/applications/main/lfrfid/scenes/lfrfid_scene_delete_success.c @@ -1,17 +1,11 @@ #include "../lfrfid_i.h" -#include "../../../settings/desktop_settings/desktop_settings_app.h" +#include "../../../settings/xtreme_settings/xtreme_assets.h" void lfrfid_scene_delete_success_on_enter(void* context) { LfRfid* app = context; Popup* popup = app->popup; - DesktopSettings* settings = malloc(sizeof(DesktopSettings)); - DESKTOP_SETTINGS_LOAD(settings); - if(settings->sfw_mode) { - popup_set_icon(popup, 0, 2, &I_DolphinMafia_115x62_sfw); - } else { - popup_set_icon(popup, 0, 2, &I_DolphinMafia_115x62); - } + popup_set_icon(popup, 0, 2, XTREME_ASSETS()->I_DolphinMafia_115x62); popup_set_header(popup, "Deleted", 83, 19, AlignLeft, AlignBottom); popup_set_context(popup, app); popup_set_callback(popup, lfrfid_popup_timeout_callback); @@ -19,7 +13,6 @@ void lfrfid_scene_delete_success_on_enter(void* context) { popup_enable_timeout(popup); view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidViewPopup); - free(settings); } bool lfrfid_scene_delete_success_on_event(void* context, SceneManagerEvent event) { diff --git a/applications/main/lfrfid/scenes/lfrfid_scene_emulate.c b/applications/main/lfrfid/scenes/lfrfid_scene_emulate.c index 4bc3ceb223..9132f4a917 100644 --- a/applications/main/lfrfid/scenes/lfrfid_scene_emulate.c +++ b/applications/main/lfrfid/scenes/lfrfid_scene_emulate.c @@ -1,11 +1,9 @@ #include "../lfrfid_i.h" -#include "../../../settings/desktop_settings/desktop_settings_app.h" +#include "../../../settings/xtreme_settings/xtreme_assets.h" void lfrfid_scene_emulate_on_enter(void* context) { LfRfid* app = context; Popup* popup = app->popup; - DesktopSettings* settings = malloc(sizeof(DesktopSettings)); - DESKTOP_SETTINGS_LOAD(settings); popup_set_header(popup, "Emulating", 89, 30, AlignCenter, AlignTop); if(!furi_string_empty(app->file_name)) { @@ -19,18 +17,13 @@ void lfrfid_scene_emulate_on_enter(void* context) { AlignCenter, AlignTop); } - if(settings->sfw_mode) { - popup_set_icon(popup, 0, 3, &I_RFIDDolphinSend_97x61_sfw); - } else { - popup_set_icon(popup, 0, 3, &I_RFIDDolphinSend_97x61); - } + popup_set_icon(popup, 0, 3, XTREME_ASSETS()->I_RFIDDolphinSend_97x61); 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); - free(settings); } bool lfrfid_scene_emulate_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 b8da7e04c7..73e1dbbb9e 100644 --- a/applications/main/lfrfid/scenes/lfrfid_scene_raw_read.c +++ b/applications/main/lfrfid/scenes/lfrfid_scene_raw_read.c @@ -1,5 +1,5 @@ #include "../lfrfid_i.h" -#include "../../../settings/desktop_settings/desktop_settings_app.h" +#include "../../../settings/xtreme_settings/xtreme_assets.h" #define RAW_READ_TIME 5000 @@ -29,17 +29,11 @@ static void timer_callback(void* context) { void lfrfid_scene_raw_read_on_enter(void* context) { LfRfid* app = context; Popup* popup = app->popup; - DesktopSettings* settings = malloc(sizeof(DesktopSettings)); - DESKTOP_SETTINGS_LOAD(settings); LfRfidReadRawState* state = malloc(sizeof(LfRfidReadRawState)); scene_manager_set_scene_state(app->scene_manager, LfRfidSceneRawRead, (uint32_t)state); state->string_file_name = furi_string_alloc(); - if(settings->sfw_mode) { - popup_set_icon(popup, 0, 3, &I_RFIDDolphinReceive_97x61_sfw); - } else { - popup_set_icon(popup, 0, 3, &I_RFIDDolphinReceive_97x61); - } + popup_set_icon(popup, 0, 3, XTREME_ASSETS()->I_RFIDDolphinReceive_97x61); view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidViewPopup); lfrfid_worker_start_thread(app->lfworker); lfrfid_make_app_folder(app); @@ -64,7 +58,6 @@ void lfrfid_scene_raw_read_on_enter(void* context) { state->is_psk = false; state->error = false; - free(settings); } bool lfrfid_scene_raw_read_on_event(void* context, SceneManagerEvent event) { diff --git a/applications/main/lfrfid/scenes/lfrfid_scene_rpc.c b/applications/main/lfrfid/scenes/lfrfid_scene_rpc.c index 4b0f52d499..c11dd1109d 100644 --- a/applications/main/lfrfid/scenes/lfrfid_scene_rpc.c +++ b/applications/main/lfrfid/scenes/lfrfid_scene_rpc.c @@ -1,26 +1,19 @@ #include "../lfrfid_i.h" -#include "../../../settings/desktop_settings/desktop_settings_app.h" +#include "../../../settings/xtreme_settings/xtreme_assets.h" void lfrfid_scene_rpc_on_enter(void* context) { LfRfid* app = context; Popup* popup = app->popup; - DesktopSettings* settings = malloc(sizeof(DesktopSettings)); - DESKTOP_SETTINGS_LOAD(settings); popup_set_header(popup, "LF RFID", 89, 42, AlignCenter, AlignBottom); popup_set_text(popup, "RPC mode", 89, 44, AlignCenter, AlignTop); - if(settings->sfw_mode) { - popup_set_icon(popup, 0, 12, &I_RFIDDolphinSend_97x61_sfw); - } else { - popup_set_icon(popup, 0, 12, &I_RFIDDolphinSend_97x61); - } + popup_set_icon(popup, 0, 12, XTREME_ASSETS()->I_RFIDDolphinSend_97x61); view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidViewPopup); notification_message(app->notifications, &sequence_display_backlight_on); app->rpc_state = LfRfidRpcStateIdle; - free(settings); } bool lfrfid_scene_rpc_on_event(void* context, SceneManagerEvent event) { diff --git a/applications/main/lfrfid/scenes/lfrfid_scene_save_success.c b/applications/main/lfrfid/scenes/lfrfid_scene_save_success.c index 5521bb0f75..4003ee4053 100644 --- a/applications/main/lfrfid/scenes/lfrfid_scene_save_success.c +++ b/applications/main/lfrfid/scenes/lfrfid_scene_save_success.c @@ -1,19 +1,13 @@ #include "../lfrfid_i.h" -#include "../../../settings/desktop_settings/desktop_settings_app.h" +#include "../../../settings/xtreme_settings/xtreme_assets.h" void lfrfid_scene_save_success_on_enter(void* context) { LfRfid* app = context; Popup* popup = app->popup; - DesktopSettings* settings = malloc(sizeof(DesktopSettings)); - DESKTOP_SETTINGS_LOAD(settings); // Clear state of data enter scene scene_manager_set_scene_state(app->scene_manager, LfRfidSceneSaveData, 0); - if(settings->sfw_mode) { - popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59_sfw); - } else { - popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59); - } + popup_set_icon(popup, 32, 5, XTREME_ASSETS()->I_DolphinNice_96x59); popup_set_header(popup, "Saved!", 5, 7, AlignLeft, AlignTop); popup_set_context(popup, app); popup_set_callback(popup, lfrfid_popup_timeout_callback); @@ -21,7 +15,6 @@ void lfrfid_scene_save_success_on_enter(void* context) { popup_enable_timeout(popup); view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidViewPopup); - free(settings); } bool lfrfid_scene_save_success_on_event(void* context, SceneManagerEvent event) { diff --git a/applications/main/lfrfid/scenes/lfrfid_scene_write.c b/applications/main/lfrfid/scenes/lfrfid_scene_write.c index 549e2f9a30..9cae43c965 100644 --- a/applications/main/lfrfid/scenes/lfrfid_scene_write.c +++ b/applications/main/lfrfid/scenes/lfrfid_scene_write.c @@ -1,5 +1,5 @@ #include "../lfrfid_i.h" -#include "../../../settings/desktop_settings/desktop_settings_app.h" +#include "../../../settings/xtreme_settings/xtreme_assets.h" static void lfrfid_write_callback(LFRFIDWorkerWriteResult result, void* context) { LfRfid* app = context; @@ -21,8 +21,6 @@ static void lfrfid_write_callback(LFRFIDWorkerWriteResult result, void* context) void lfrfid_scene_write_on_enter(void* context) { LfRfid* app = context; Popup* popup = app->popup; - DesktopSettings* settings = malloc(sizeof(DesktopSettings)); - DESKTOP_SETTINGS_LOAD(settings); popup_set_header(popup, "Writing", 89, 30, AlignCenter, AlignTop); if(!furi_string_empty(app->file_name)) { @@ -36,11 +34,7 @@ void lfrfid_scene_write_on_enter(void* context) { AlignCenter, AlignTop); } - if(settings->sfw_mode) { - popup_set_icon(popup, 0, 3, &I_RFIDDolphinSend_97x61_sfw); - } else { - popup_set_icon(popup, 0, 3, &I_RFIDDolphinSend_97x61); - } + popup_set_icon(popup, 0, 3, XTREME_ASSETS()->I_RFIDDolphinSend_97x61); view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidViewPopup); @@ -51,7 +45,6 @@ void lfrfid_scene_write_on_enter(void* context) { lfrfid_worker_write_start( app->lfworker, (LFRFIDProtocol)app->protocol_id, lfrfid_write_callback, app); notification_message(app->notifications, &sequence_blink_start_magenta); - free(settings); } bool lfrfid_scene_write_on_event(void* context, SceneManagerEvent event) { diff --git a/applications/main/lfrfid/scenes/lfrfid_scene_write_success.c b/applications/main/lfrfid/scenes/lfrfid_scene_write_success.c index 27552f4170..48d0462277 100644 --- a/applications/main/lfrfid/scenes/lfrfid_scene_write_success.c +++ b/applications/main/lfrfid/scenes/lfrfid_scene_write_success.c @@ -1,18 +1,12 @@ #include "../lfrfid_i.h" -#include "../../../settings/desktop_settings/desktop_settings_app.h" +#include "../../../settings/xtreme_settings/xtreme_assets.h" void lfrfid_scene_write_success_on_enter(void* context) { LfRfid* app = context; Popup* popup = app->popup; - DesktopSettings* settings = malloc(sizeof(DesktopSettings)); - DESKTOP_SETTINGS_LOAD(settings); popup_set_header(popup, "Successfully\nwritten!", 94, 3, AlignCenter, AlignTop); - if(settings->sfw_mode) { - popup_set_icon(popup, 0, 6, &I_RFIDDolphinSuccess_108x57_sfw); - } else { - popup_set_icon(popup, 0, 6, &I_RFIDDolphinSuccess_108x57); - } + popup_set_icon(popup, 0, 6, XTREME_ASSETS()->I_RFIDDolphinSuccess_108x57); popup_set_context(popup, app); popup_set_callback(popup, lfrfid_popup_timeout_callback); popup_set_timeout(popup, 1500); @@ -20,7 +14,6 @@ void lfrfid_scene_write_success_on_enter(void* context) { view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidViewPopup); notification_message_block(app->notifications, &sequence_set_green_255); - free(settings); } bool lfrfid_scene_write_success_on_event(void* context, SceneManagerEvent event) { diff --git a/applications/main/nfc/scenes/nfc_scene_delete_success.c b/applications/main/nfc/scenes/nfc_scene_delete_success.c index 5da15f91f8..a732f53846 100644 --- a/applications/main/nfc/scenes/nfc_scene_delete_success.c +++ b/applications/main/nfc/scenes/nfc_scene_delete_success.c @@ -1,5 +1,5 @@ #include "../nfc_i.h" -#include "../../../settings/desktop_settings/desktop_settings_app.h" +#include "../../../settings/xtreme_settings/xtreme_assets.h" void nfc_scene_delete_success_popup_callback(void* context) { Nfc* nfc = context; @@ -8,23 +8,16 @@ void nfc_scene_delete_success_popup_callback(void* context) { void nfc_scene_delete_success_on_enter(void* context) { Nfc* nfc = context; - DesktopSettings* settings = malloc(sizeof(DesktopSettings)); - DESKTOP_SETTINGS_LOAD(settings); // Setup view Popup* popup = nfc->popup; - if(settings->sfw_mode) { - popup_set_icon(popup, 0, 2, &I_DolphinMafia_115x62_sfw); - } else { - popup_set_icon(popup, 0, 2, &I_DolphinMafia_115x62); - } + popup_set_icon(popup, 0, 2, XTREME_ASSETS()->I_DolphinMafia_115x62); popup_set_header(popup, "Deleted", 83, 19, AlignLeft, AlignBottom); popup_set_timeout(popup, 1500); popup_set_context(popup, nfc); popup_set_callback(popup, nfc_scene_delete_success_popup_callback); popup_enable_timeout(popup); view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewPopup); - free(settings); } bool nfc_scene_delete_success_on_event(void* context, SceneManagerEvent event) { diff --git a/applications/main/nfc/scenes/nfc_scene_emulate_nfcv.c b/applications/main/nfc/scenes/nfc_scene_emulate_nfcv.c index d9d3db9da4..f423efc380 100644 --- a/applications/main/nfc/scenes/nfc_scene_emulate_nfcv.c +++ b/applications/main/nfc/scenes/nfc_scene_emulate_nfcv.c @@ -1,5 +1,5 @@ #include "../nfc_i.h" -#include "../../../settings/desktop_settings/desktop_settings_app.h" +#include "../../../settings/xtreme_settings/xtreme_assets.h" #define NFC_SCENE_EMULATE_NFCV_LOG_SIZE_MAX (100) @@ -38,14 +38,7 @@ static void nfc_scene_emulate_nfcv_widget_config(Nfc* nfc, bool data_received) { FuriString* info_str; info_str = furi_string_alloc(); - DesktopSettings* settings = malloc(sizeof(DesktopSettings)); - DESKTOP_SETTINGS_LOAD(settings); - - if(settings->sfw_mode) { - widget_add_icon_element(widget, 0, 3, &I_RFIDDolphinSend_97x61_sfw); - } else { - widget_add_icon_element(widget, 0, 3, &I_RFIDDolphinSend_97x61); - } + widget_add_icon_element(widget, 0, 3, XTREME_ASSETS()->I_RFIDDolphinSend_97x61); widget_add_string_element( widget, 89, 32, AlignCenter, AlignTop, FontPrimary, "Emulating NfcV"); @@ -64,7 +57,6 @@ static void nfc_scene_emulate_nfcv_widget_config(Nfc* nfc, bool data_received) { widget_add_button_element( widget, GuiButtonTypeCenter, "Log", nfc_scene_emulate_nfcv_widget_callback, nfc); } - free(settings); } void nfc_scene_emulate_nfcv_on_enter(void* context) { diff --git a/applications/main/nfc/scenes/nfc_scene_emulate_uid.c b/applications/main/nfc/scenes/nfc_scene_emulate_uid.c index e935ad18cf..a583ac12d0 100644 --- a/applications/main/nfc/scenes/nfc_scene_emulate_uid.c +++ b/applications/main/nfc/scenes/nfc_scene_emulate_uid.c @@ -1,5 +1,5 @@ #include "../nfc_i.h" -#include "../../../settings/desktop_settings/desktop_settings_app.h" +#include "../../../settings/xtreme_settings/xtreme_assets.h" #define NFC_SCENE_EMULATE_UID_LOG_SIZE_MAX (200) @@ -37,14 +37,8 @@ static void nfc_scene_emulate_uid_widget_config(Nfc* nfc, bool data_received) { widget_reset(widget); FuriString* info_str; info_str = furi_string_alloc(); - DesktopSettings* settings = malloc(sizeof(DesktopSettings)); - DESKTOP_SETTINGS_LOAD(settings); - if(settings->sfw_mode) { - widget_add_icon_element(widget, 0, 3, &I_NFC_dolphin_emulation_47x61_sfw); - } else { - widget_add_icon_element(widget, 0, 3, &I_NFC_dolphin_emulation_47x61); - } + widget_add_icon_element(widget, 0, 3, XTREME_ASSETS()->I_NFC_dolphin_emulation_47x61); widget_add_string_element(widget, 57, 13, AlignLeft, AlignTop, FontPrimary, "Emulating UID"); if(strcmp(nfc->dev->dev_name, "") != 0) { furi_string_printf(info_str, "%s", nfc->dev->dev_name); @@ -61,7 +55,6 @@ static void nfc_scene_emulate_uid_widget_config(Nfc* nfc, bool data_received) { widget_add_button_element( widget, GuiButtonTypeCenter, "Log", nfc_scene_emulate_uid_widget_callback, nfc); } - free(settings); } void nfc_scene_emulate_uid_on_enter(void* context) { diff --git a/applications/main/nfc/scenes/nfc_scene_mf_classic_emulate.c b/applications/main/nfc/scenes/nfc_scene_mf_classic_emulate.c index 3a0b597e9c..1d2e1784f2 100644 --- a/applications/main/nfc/scenes/nfc_scene_mf_classic_emulate.c +++ b/applications/main/nfc/scenes/nfc_scene_mf_classic_emulate.c @@ -1,5 +1,5 @@ #include "../nfc_i.h" -#include "../../../settings/desktop_settings/desktop_settings_app.h" +#include "../../../settings/xtreme_settings/xtreme_assets.h" #define NFC_MF_CLASSIC_DATA_NOT_CHANGED (0UL) #define NFC_MF_CLASSIC_DATA_CHANGED (1UL) @@ -15,8 +15,6 @@ bool nfc_mf_classic_emulate_worker_callback(NfcWorkerEvent event, void* context) void nfc_scene_mf_classic_emulate_on_enter(void* context) { Nfc* nfc = context; - DesktopSettings* settings = malloc(sizeof(DesktopSettings)); - DESKTOP_SETTINGS_LOAD(settings); // Setup view Popup* popup = nfc->popup; @@ -26,11 +24,7 @@ void nfc_scene_mf_classic_emulate_on_enter(void* context) { } else { nfc_text_store_set(nfc, "MIFARE\nClassic"); } - if(settings->sfw_mode) { - popup_set_icon(popup, 0, 3, &I_NFC_dolphin_emulation_47x61_sfw); - } else { - popup_set_icon(popup, 0, 3, &I_NFC_dolphin_emulation_47x61); - } + popup_set_icon(popup, 0, 3, XTREME_ASSETS()->I_NFC_dolphin_emulation_47x61); popup_set_text(popup, nfc->text_store, 90, 28, AlignCenter, AlignTop); // Setup and start worker @@ -42,7 +36,6 @@ void nfc_scene_mf_classic_emulate_on_enter(void* context) { nfc_mf_classic_emulate_worker_callback, nfc); nfc_blink_emulate_start(nfc); - free(settings); } bool nfc_scene_mf_classic_emulate_on_event(void* context, SceneManagerEvent event) { diff --git a/applications/main/nfc/scenes/nfc_scene_mf_classic_update_success.c b/applications/main/nfc/scenes/nfc_scene_mf_classic_update_success.c index 9bd354c854..3c2c724bd9 100644 --- a/applications/main/nfc/scenes/nfc_scene_mf_classic_update_success.c +++ b/applications/main/nfc/scenes/nfc_scene_mf_classic_update_success.c @@ -1,6 +1,6 @@ #include "../nfc_i.h" #include -#include "../../../settings/desktop_settings/desktop_settings_app.h" +#include "../../../settings/xtreme_settings/xtreme_assets.h" void nfc_scene_mf_classic_update_success_popup_callback(void* context) { Nfc* nfc = context; @@ -10,17 +10,11 @@ void nfc_scene_mf_classic_update_success_popup_callback(void* context) { void nfc_scene_mf_classic_update_success_on_enter(void* context) { Nfc* nfc = context; DOLPHIN_DEED(DolphinDeedNfcSave); - DesktopSettings* settings = malloc(sizeof(DesktopSettings)); - DESKTOP_SETTINGS_LOAD(settings); notification_message(nfc->notifications, &sequence_success); Popup* popup = nfc->popup; - if(settings->sfw_mode) { - popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59_sfw); - } else { - popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59); - } + popup_set_icon(popup, 32, 5, XTREME_ASSETS()->I_DolphinNice_96x59); popup_set_header(popup, "Updated!", 11, 20, AlignLeft, AlignBottom); popup_set_timeout(popup, 1500); popup_set_context(popup, nfc); @@ -28,7 +22,6 @@ void nfc_scene_mf_classic_update_success_on_enter(void* context) { popup_enable_timeout(popup); view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewPopup); - free(settings); } bool nfc_scene_mf_classic_update_success_on_event(void* context, SceneManagerEvent event) { diff --git a/applications/main/nfc/scenes/nfc_scene_mf_classic_write_success.c b/applications/main/nfc/scenes/nfc_scene_mf_classic_write_success.c index 25656c072a..f16d2f733e 100644 --- a/applications/main/nfc/scenes/nfc_scene_mf_classic_write_success.c +++ b/applications/main/nfc/scenes/nfc_scene_mf_classic_write_success.c @@ -1,6 +1,6 @@ #include "../nfc_i.h" #include -#include "../../../settings/desktop_settings/desktop_settings_app.h" +#include "../../../settings/xtreme_settings/xtreme_assets.h" void nfc_scene_mf_classic_write_success_popup_callback(void* context) { Nfc* nfc = context; @@ -10,17 +10,11 @@ void nfc_scene_mf_classic_write_success_popup_callback(void* context) { void nfc_scene_mf_classic_write_success_on_enter(void* context) { Nfc* nfc = context; DOLPHIN_DEED(DolphinDeedNfcSave); - DesktopSettings* settings = malloc(sizeof(DesktopSettings)); - DESKTOP_SETTINGS_LOAD(settings); notification_message(nfc->notifications, &sequence_success); Popup* popup = nfc->popup; - if(settings->sfw_mode) { - popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59_sfw); - } else { - popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59); - } + popup_set_icon(popup, 32, 5, XTREME_ASSETS()->I_DolphinNice_96x59); popup_set_header(popup, "Successfully\nwritten", 13, 22, AlignLeft, AlignBottom); popup_set_timeout(popup, 1500); popup_set_context(popup, nfc); @@ -28,7 +22,6 @@ void nfc_scene_mf_classic_write_success_on_enter(void* context) { popup_enable_timeout(popup); view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewPopup); - free(settings); } bool nfc_scene_mf_classic_write_success_on_event(void* context, SceneManagerEvent event) { diff --git a/applications/main/nfc/scenes/nfc_scene_mf_ultralight_emulate.c b/applications/main/nfc/scenes/nfc_scene_mf_ultralight_emulate.c index 7e8a899a46..d50ad5b84a 100644 --- a/applications/main/nfc/scenes/nfc_scene_mf_ultralight_emulate.c +++ b/applications/main/nfc/scenes/nfc_scene_mf_ultralight_emulate.c @@ -1,6 +1,6 @@ #include "../nfc_i.h" #include -#include "../../../settings/desktop_settings/desktop_settings_app.h" +#include "../../../settings/xtreme_settings/xtreme_assets.h" #define NFC_SCENE_MF_ULTRALIGHT_EMULATE_LOG_SIZE_MAX (200) @@ -66,14 +66,7 @@ void nfc_scene_mf_ultralight_emulate_widget_config(Nfc* nfc, bool auth_attempted FuriString* info_str; info_str = furi_string_alloc(); - DesktopSettings* settings = malloc(sizeof(DesktopSettings)); - DESKTOP_SETTINGS_LOAD(settings); - - if(settings->sfw_mode) { - widget_add_icon_element(widget, 0, 3, &I_NFC_dolphin_emulation_47x61_sfw); - } else { - widget_add_icon_element(widget, 0, 3, &I_NFC_dolphin_emulation_47x61); - } + widget_add_icon_element(widget, 0, 3, XTREME_ASSETS()->I_NFC_dolphin_emulation_47x61); if(strcmp(nfc->dev->dev_name, "")) { furi_string_printf(info_str, "Emulating\n%s", nfc->dev->dev_name); @@ -92,15 +85,12 @@ void nfc_scene_mf_ultralight_emulate_widget_config(Nfc* nfc, bool auth_attempted nfc_scene_mf_ultralight_emulate_widget_callback, nfc); } - free(settings); } void nfc_scene_mf_ultralight_emulate_on_enter(void* context) { Nfc* nfc = context; uint32_t state = scene_manager_get_scene_state(nfc->scene_manager, NfcSceneMfUltralightEmulate); - DesktopSettings* settings = malloc(sizeof(DesktopSettings)); - DESKTOP_SETTINGS_LOAD(settings); // Setup Widget nfc_scene_mf_ultralight_emulate_widget_config(nfc, false); @@ -123,11 +113,7 @@ void nfc_scene_mf_ultralight_emulate_on_enter(void* context) { } else { nfc_text_store_set(nfc, "MIFARE\nNTAG"); } - if(settings->sfw_mode) { - popup_set_icon(popup, 0, 3, &I_NFC_dolphin_emulation_47x61_sfw); - } else { - popup_set_icon(popup, 0, 3, &I_NFC_dolphin_emulation_47x61); - } + popup_set_icon(popup, 0, 3, XTREME_ASSETS()->I_NFC_dolphin_emulation_47x61); popup_set_text(popup, nfc->text_store, 90, 28, AlignCenter, AlignTop); // Set Widget state and view @@ -143,7 +129,6 @@ void nfc_scene_mf_ultralight_emulate_on_enter(void* context) { nfc_mf_ultralight_emulate_worker_callback, nfc); nfc_blink_emulate_start(nfc); - free(settings); } bool nfc_scene_mf_ultralight_emulate_on_event(void* context, SceneManagerEvent event) { diff --git a/applications/main/nfc/scenes/nfc_scene_restore_original.c b/applications/main/nfc/scenes/nfc_scene_restore_original.c index b87c2f7909..3794b438d0 100644 --- a/applications/main/nfc/scenes/nfc_scene_restore_original.c +++ b/applications/main/nfc/scenes/nfc_scene_restore_original.c @@ -1,5 +1,5 @@ #include "../nfc_i.h" -#include "../../../settings/desktop_settings/desktop_settings_app.h" +#include "../../../settings/xtreme_settings/xtreme_assets.h" void nfc_scene_restore_original_popup_callback(void* context) { Nfc* nfc = context; @@ -8,23 +8,16 @@ void nfc_scene_restore_original_popup_callback(void* context) { void nfc_scene_restore_original_on_enter(void* context) { Nfc* nfc = context; - DesktopSettings* settings = malloc(sizeof(DesktopSettings)); - DESKTOP_SETTINGS_LOAD(settings); // Setup view Popup* popup = nfc->popup; - if(settings->sfw_mode) { - popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59_sfw); - } else { - popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59); - } + popup_set_icon(popup, 32, 5, XTREME_ASSETS()->I_DolphinNice_96x59); popup_set_header(popup, "Original file\nrestored", 13, 22, AlignLeft, AlignBottom); popup_set_timeout(popup, 1500); popup_set_context(popup, nfc); popup_set_callback(popup, nfc_scene_restore_original_popup_callback); popup_enable_timeout(popup); view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewPopup); - free(settings); } bool nfc_scene_restore_original_on_event(void* context, SceneManagerEvent event) { diff --git a/applications/main/nfc/scenes/nfc_scene_rpc.c b/applications/main/nfc/scenes/nfc_scene_rpc.c index 9bd55577d9..e6b31fffa4 100644 --- a/applications/main/nfc/scenes/nfc_scene_rpc.c +++ b/applications/main/nfc/scenes/nfc_scene_rpc.c @@ -1,25 +1,18 @@ #include "../nfc_i.h" -#include "../../../settings/desktop_settings/desktop_settings_app.h" +#include "../../../settings/xtreme_settings/xtreme_assets.h" void nfc_scene_rpc_on_enter(void* context) { Nfc* nfc = context; Popup* popup = nfc->popup; - DesktopSettings* settings = malloc(sizeof(DesktopSettings)); - DESKTOP_SETTINGS_LOAD(settings); popup_set_header(popup, "NFC", 89, 42, AlignCenter, AlignBottom); popup_set_text(popup, "RPC mode", 89, 44, AlignCenter, AlignTop); - if(settings->sfw_mode) { - popup_set_icon(popup, 0, 12, &I_NFC_dolphin_emulation_47x61_sfw); - } else { - popup_set_icon(popup, 0, 12, &I_NFC_dolphin_emulation_47x61); - } + popup_set_icon(popup, 0, 12, XTREME_ASSETS()->I_NFC_dolphin_emulation_47x61); view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewPopup); notification_message(nfc->notifications, &sequence_display_backlight_on); - free(settings); } static bool nfc_scene_rpc_emulate_callback(NfcWorkerEvent event, void* context) { diff --git a/applications/main/nfc/scenes/nfc_scene_save_success.c b/applications/main/nfc/scenes/nfc_scene_save_success.c index 58b7d1bf41..a9359c434a 100644 --- a/applications/main/nfc/scenes/nfc_scene_save_success.c +++ b/applications/main/nfc/scenes/nfc_scene_save_success.c @@ -1,5 +1,5 @@ #include "../nfc_i.h" -#include "../../../settings/desktop_settings/desktop_settings_app.h" +#include "../../../settings/xtreme_settings/xtreme_assets.h" void nfc_scene_save_success_popup_callback(void* context) { Nfc* nfc = context; @@ -8,23 +8,16 @@ void nfc_scene_save_success_popup_callback(void* context) { void nfc_scene_save_success_on_enter(void* context) { Nfc* nfc = context; - DesktopSettings* settings = malloc(sizeof(DesktopSettings)); - DESKTOP_SETTINGS_LOAD(settings); // Setup view Popup* popup = nfc->popup; - if(settings->sfw_mode) { - popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59_sfw); - } else { - popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59); - } + popup_set_icon(popup, 32, 5, XTREME_ASSETS()->I_DolphinNice_96x59); popup_set_header(popup, "Saved!", 13, 22, AlignLeft, AlignBottom); popup_set_timeout(popup, 1500); popup_set_context(popup, nfc); popup_set_callback(popup, nfc_scene_save_success_popup_callback); popup_enable_timeout(popup); view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewPopup); - free(settings); } bool nfc_scene_save_success_on_event(void* context, SceneManagerEvent event) { diff --git a/applications/main/subghz/scenes/subghz_scene_delete_success.c b/applications/main/subghz/scenes/subghz_scene_delete_success.c index e30eda7853..4f00df70ba 100644 --- a/applications/main/subghz/scenes/subghz_scene_delete_success.c +++ b/applications/main/subghz/scenes/subghz_scene_delete_success.c @@ -1,6 +1,6 @@ #include "../subghz_i.h" #include "../helpers/subghz_custom_event.h" -#include "../../../settings/desktop_settings/desktop_settings_app.h" +#include "../../../settings/xtreme_settings/xtreme_assets.h" void subghz_scene_delete_success_popup_callback(void* context) { SubGhz* subghz = context; @@ -10,23 +10,16 @@ void subghz_scene_delete_success_popup_callback(void* context) { void subghz_scene_delete_success_on_enter(void* context) { SubGhz* subghz = context; - DesktopSettings* settings = malloc(sizeof(DesktopSettings)); - DESKTOP_SETTINGS_LOAD(settings); // Setup view Popup* popup = subghz->popup; - if(settings->sfw_mode) { - popup_set_icon(popup, 0, 2, &I_DolphinMafia_115x62_sfw); - } else { - popup_set_icon(popup, 0, 2, &I_DolphinMafia_115x62); - } + popup_set_icon(popup, 0, 2, XTREME_ASSETS()->I_DolphinMafia_115x62); popup_set_header(popup, "Deleted", 83, 19, AlignLeft, AlignBottom); popup_set_timeout(popup, 1500); popup_set_context(popup, subghz); popup_set_callback(popup, subghz_scene_delete_success_popup_callback); popup_enable_timeout(popup); view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewIdPopup); - free(settings); } bool subghz_scene_delete_success_on_event(void* context, SceneManagerEvent event) { diff --git a/applications/main/subghz/scenes/subghz_scene_rpc.c b/applications/main/subghz/scenes/subghz_scene_rpc.c index 12a5787ade..2a61d5dc58 100644 --- a/applications/main/subghz/scenes/subghz_scene_rpc.c +++ b/applications/main/subghz/scenes/subghz_scene_rpc.c @@ -1,7 +1,7 @@ #include "../subghz_i.h" #include #include -#include "../../../settings/desktop_settings/desktop_settings_app.h" +#include "../../../settings/xtreme_settings/xtreme_assets.h" typedef enum { SubGhzRpcStateIdle, @@ -11,23 +11,16 @@ typedef enum { void subghz_scene_rpc_on_enter(void* context) { SubGhz* subghz = context; Popup* popup = subghz->popup; - DesktopSettings* settings = malloc(sizeof(DesktopSettings)); - DESKTOP_SETTINGS_LOAD(settings); popup_set_header(popup, "Sub-GHz", 89, 42, AlignCenter, AlignBottom); popup_set_text(popup, "RPC mode", 89, 44, AlignCenter, AlignTop); - if(settings->sfw_mode) { - popup_set_icon(popup, 0, 12, &I_RFIDDolphinSend_97x61_sfw); - } else { - popup_set_icon(popup, 0, 12, &I_RFIDDolphinSend_97x61); - } + popup_set_icon(popup, 0, 12, XTREME_ASSETS()->I_RFIDDolphinSend_97x61); view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewIdPopup); scene_manager_set_scene_state(subghz->scene_manager, SubGhzSceneRpc, SubGhzRpcStateIdle); notification_message(subghz->notifications, &sequence_display_backlight_on); - free(settings); } bool subghz_scene_rpc_on_event(void* context, SceneManagerEvent event) { diff --git a/applications/main/subghz/scenes/subghz_scene_save_success.c b/applications/main/subghz/scenes/subghz_scene_save_success.c index 76e30d088a..bf8ed0185e 100644 --- a/applications/main/subghz/scenes/subghz_scene_save_success.c +++ b/applications/main/subghz/scenes/subghz_scene_save_success.c @@ -1,6 +1,6 @@ #include "../subghz_i.h" #include "../helpers/subghz_custom_event.h" -#include "../../../settings/desktop_settings/desktop_settings_app.h" +#include "../../../settings/xtreme_settings/xtreme_assets.h" void subghz_scene_save_success_popup_callback(void* context) { SubGhz* subghz = context; @@ -9,23 +9,16 @@ void subghz_scene_save_success_popup_callback(void* context) { void subghz_scene_save_success_on_enter(void* context) { SubGhz* subghz = context; - DesktopSettings* settings = malloc(sizeof(DesktopSettings)); - DESKTOP_SETTINGS_LOAD(settings); // Setup view Popup* popup = subghz->popup; - if(settings->sfw_mode) { - popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59_sfw); - } else { - popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59); - } + popup_set_icon(popup, 32, 5, XTREME_ASSETS()->I_DolphinNice_96x59); popup_set_header(popup, "Saved!", 13, 22, AlignLeft, AlignBottom); popup_set_timeout(popup, 1500); popup_set_context(popup, subghz); popup_set_callback(popup, subghz_scene_save_success_popup_callback); popup_enable_timeout(popup); view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewIdPopup); - free(settings); } bool subghz_scene_save_success_on_event(void* context, SceneManagerEvent event) { diff --git a/applications/main/subghz/views/receiver.c b/applications/main/subghz/views/receiver.c index 637ca86328..0a219a48cf 100644 --- a/applications/main/subghz/views/receiver.c +++ b/applications/main/subghz/views/receiver.c @@ -7,7 +7,7 @@ #include #include -#include "../../../settings/desktop_settings/desktop_settings_app.h" +#include "../../../settings/xtreme_settings/xtreme_assets.h" #define FRAME_HEIGHT 12 #define MAX_LEN_PX 111 @@ -195,8 +195,6 @@ void subghz_view_receiver_draw(Canvas* canvas, SubGhzViewReceiverModel* model) { canvas_clear(canvas); canvas_set_color(canvas, ColorBlack); canvas_set_font(canvas, FontSecondary); - DesktopSettings* settings = malloc(sizeof(DesktopSettings)); - DESKTOP_SETTINGS_LOAD(settings); if(model->mode == SubGhzViewReceiverModeLive) { elements_button_left(canvas, "Config"); @@ -234,21 +232,13 @@ void subghz_view_receiver_draw(Canvas* canvas, SubGhzViewReceiverModel* model) { if(model->history_item == 0) { if(model->mode == SubGhzViewReceiverModeLive) { - if(settings->sfw_mode) { - canvas_draw_icon(canvas, 0, 0, &I_Scanning_123x52_sfw); - } else { - canvas_draw_icon(canvas, 0, 0, &I_Scanning_123x52); - } + canvas_draw_icon(canvas, 0, 0, XTREME_ASSETS()->I_Scanning_123x52); canvas_set_font(canvas, FontPrimary); canvas_draw_str(canvas, 63, 46, "Scanning..."); canvas_draw_line(canvas, 46, 51, 125, 51); canvas_set_font(canvas, FontSecondary); } else { - if(settings->sfw_mode) { - canvas_draw_icon(canvas, 0, 0, &I_Scanning_123x52_sfw); - } else { - canvas_draw_icon(canvas, 0, 0, &I_Scanning_123x52); - } + canvas_draw_icon(canvas, 0, 0, XTREME_ASSETS()->I_Scanning_123x52); canvas_set_font(canvas, FontPrimary); canvas_draw_str(canvas, 63, 46, "Decoding..."); canvas_set_font(canvas, FontSecondary); @@ -302,7 +292,6 @@ void subghz_view_receiver_draw(Canvas* canvas, SubGhzViewReceiverModel* model) { canvas_draw_str(canvas, 96, 62, furi_string_get_cstr(model->history_stat_str)); } break; } - free(settings); } static void subghz_view_receiver_timer_callback(void* context) { diff --git a/applications/main/u2f/scenes/u2f_scene_error.c b/applications/main/u2f/scenes/u2f_scene_error.c index a4cfd38191..162faf2f11 100644 --- a/applications/main/u2f/scenes/u2f_scene_error.c +++ b/applications/main/u2f/scenes/u2f_scene_error.c @@ -1,5 +1,5 @@ #include "../u2f_app_i.h" -#include "../../../settings/desktop_settings/desktop_settings_app.h" +#include "../../../settings/xtreme_settings/xtreme_settings.h" static void u2f_scene_error_event_callback(GuiButtonType result, InputType type, void* context) { furi_assert(context); @@ -12,8 +12,6 @@ static void u2f_scene_error_event_callback(GuiButtonType result, InputType type, void u2f_scene_error_on_enter(void* context) { U2fApp* app = context; - DesktopSettings* settings = malloc(sizeof(DesktopSettings)); - DESKTOP_SETTINGS_LOAD(settings); if(app->error == U2fAppErrorNoFiles) { widget_add_icon_element(app->widget, 0, 0, &I_SDQuestion_35x43); @@ -29,9 +27,9 @@ void u2f_scene_error_on_enter(void* context) { app->widget, GuiButtonTypeLeft, "Back", u2f_scene_error_event_callback, app); } else if(app->error == U2fAppErrorCloseRpc) { widget_add_icon_element(app->widget, 78, 0, &I_ActiveConnection_50x64); - if(settings->sfw_mode) { + if(XTREME_SETTINGS()->nsfw_mode) { widget_add_string_multiline_element( - app->widget, 3, 2, AlignLeft, AlignTop, FontPrimary, "Connection\nis active!"); + app->widget, 3, 2, AlignLeft, AlignTop, FontPrimary, "I am not\na whore!"); widget_add_string_multiline_element( app->widget, 3, @@ -39,10 +37,10 @@ void u2f_scene_error_on_enter(void* context) { AlignLeft, AlignTop, FontSecondary, - "Disconnect from\nPC or phone to\nuse this function."); + "Pull out from\nPC or phone to\nuse me like this."); } else { widget_add_string_multiline_element( - app->widget, 3, 2, AlignLeft, AlignTop, FontPrimary, "I am not\na whore!"); + app->widget, 3, 2, AlignLeft, AlignTop, FontPrimary, "Connection\nis active!"); widget_add_string_multiline_element( app->widget, 3, @@ -50,12 +48,11 @@ void u2f_scene_error_on_enter(void* context) { AlignLeft, AlignTop, FontSecondary, - "Pull out from\nPC or phone to\nuse me like this."); + "Disconnect from\nPC or phone to\nuse this function."); } } view_dispatcher_switch_to_view(app->view_dispatcher, U2fAppViewError); - free(settings); } bool u2f_scene_error_on_event(void* context, SceneManagerEvent event) { diff --git a/applications/main/u2f/views/u2f_view.c b/applications/main/u2f/views/u2f_view.c index 77b6a288e2..eecd327022 100644 --- a/applications/main/u2f/views/u2f_view.c +++ b/applications/main/u2f/views/u2f_view.c @@ -1,7 +1,7 @@ #include "u2f_view.h" #include #include -#include "../../../settings/desktop_settings/desktop_settings_app.h" +#include "../../../settings/xtreme_settings/xtreme_assets.h" struct U2fView { View* view; @@ -15,74 +15,63 @@ typedef struct { static void u2f_view_draw_callback(Canvas* canvas, void* _model) { U2fModel* model = _model; - DesktopSettings* settings = malloc(sizeof(DesktopSettings)); - DESKTOP_SETTINGS_LOAD(settings); canvas_draw_icon(canvas, 8, 14, &I_Drive_112x35); canvas_set_font(canvas, FontSecondary); if(model->display_msg == U2fMsgNotConnected) { - if(settings->sfw_mode) { - canvas_draw_icon(canvas, 22, 15, &I_Connect_me_62x31_sfw); + canvas_draw_icon(canvas, 22, 15, XTREME_ASSETS()->I_Connect_me_62x31); + if(XTREME_SETTINGS()->nsfw_mode) { canvas_draw_str_aligned( - canvas, 128 / 2, 3, AlignCenter, AlignTop, "Connect to a device"); + canvas, 128 / 2, 3, AlignCenter, AlignTop, "Plug me in d-daddy"); } else { - canvas_draw_icon(canvas, 22, 15, &I_Connect_me_62x31); canvas_draw_str_aligned( - canvas, 128 / 2, 3, AlignCenter, AlignTop, "Plug me in d-daddy"); + canvas, 128 / 2, 3, AlignCenter, AlignTop, "Connect to a device"); } } else if(model->display_msg == U2fMsgIdle) { - if(settings->sfw_mode) { - canvas_draw_icon(canvas, 22, 15, &I_Connected_62x31_sfw); - canvas_draw_str_aligned(canvas, 128 / 2, 3, AlignCenter, AlignTop, "Connected!"); - } else { - canvas_draw_icon(canvas, 22, 15, &I_Connected_62x31); - canvas_draw_str_aligned(canvas, 128 / 2, 3, AlignCenter, AlignTop, "Connected!"); - } + canvas_draw_icon(canvas, 22, 15, XTREME_ASSETS()->I_Connected_62x31); + canvas_draw_str_aligned(canvas, 128 / 2, 3, AlignCenter, AlignTop, "Connected!"); } else if(model->display_msg == U2fMsgRegister) { - if(settings->sfw_mode) { - elements_button_center(canvas, "OK"); - canvas_draw_icon(canvas, 22, 15, &I_Auth_62x31_sfw); - canvas_draw_str_aligned( - canvas, 128 / 2, 3, AlignCenter, AlignTop, "Press OK to register"); - } else { + if(XTREME_SETTINGS()->nsfw_mode) { elements_button_center(canvas, "CUM"); - canvas_draw_icon(canvas, 22, 15, &I_Auth_62x31); + canvas_draw_icon(canvas, 22, 15, XTREME_ASSETS()->I_Auth_62x31); canvas_draw_str_aligned( canvas, 128 / 2, 3, AlignCenter, AlignTop, "Press CUM to register"); - } - } else if(model->display_msg == U2fMsgAuth) { - if(settings->sfw_mode) { + } else { elements_button_center(canvas, "OK"); - canvas_draw_icon(canvas, 22, 15, &I_Auth_62x31_sfw); + canvas_draw_icon(canvas, 22, 15, XTREME_ASSETS()->I_Auth_62x31); canvas_draw_str_aligned( - canvas, 128 / 2, 3, AlignCenter, AlignTop, "Press OK to authenticate"); - } else { + canvas, 128 / 2, 3, AlignCenter, AlignTop, "Press OK to register"); + } + } else if(model->display_msg == U2fMsgAuth) { + if(XTREME_SETTINGS()->nsfw_mode) { elements_button_center(canvas, "CUM"); - canvas_draw_icon(canvas, 22, 15, &I_Auth_62x31); + canvas_draw_icon(canvas, 22, 15, XTREME_ASSETS()->I_Auth_62x31); canvas_draw_str_aligned( canvas, 128 / 2, 3, AlignCenter, AlignTop, "Press CUM to authenticate"); + } else { + elements_button_center(canvas, "OK"); + canvas_draw_icon(canvas, 22, 15, XTREME_ASSETS()->I_Auth_62x31); + canvas_draw_str_aligned( + canvas, 128 / 2, 3, AlignCenter, AlignTop, "Press OK to authenticate"); } } else if(model->display_msg == U2fMsgSuccess) { - if(settings->sfw_mode) { - canvas_draw_icon(canvas, 22, 15, &I_Connected_62x31_sfw); + canvas_draw_icon(canvas, 22, 15, XTREME_ASSETS()->I_Connected_62x31); + if(XTREME_SETTINGS()->nsfw_mode) { + canvas_draw_str_aligned(canvas, 128 / 2, 3, AlignCenter, AlignTop, "Cum released~"); + } else { canvas_draw_str_aligned( canvas, 128 / 2, 3, AlignCenter, AlignTop, "Authentication successful!"); - } else { - canvas_draw_icon(canvas, 22, 15, &I_Connected_62x31); - canvas_draw_str_aligned(canvas, 128 / 2, 3, AlignCenter, AlignTop, "Cum released~"); } } else if(model->display_msg == U2fMsgError) { - if(settings->sfw_mode) { - canvas_draw_icon(canvas, 22, 15, &I_Error_62x31_sfw); + canvas_draw_icon(canvas, 22, 15, XTREME_ASSETS()->I_Error_62x31); + if(XTREME_SETTINGS()->nsfw_mode) { + canvas_draw_str_aligned(canvas, 128 / 2, 3, AlignCenter, AlignTop, "Unable to cum"); + } else { canvas_draw_str_aligned( canvas, 128 / 2, 3, AlignCenter, AlignTop, "Certificate error"); - } else { - canvas_draw_icon(canvas, 22, 15, &I_Error_62x31); - canvas_draw_str_aligned(canvas, 128 / 2, 3, AlignCenter, AlignTop, "Unable to cum"); } } - free(settings); } static bool u2f_view_input_callback(InputEvent* event, void* context) { diff --git a/applications/plugins/asteroids/app.c b/applications/plugins/asteroids/app.c index 07be54c3d2..9aee8e9f03 100644 --- a/applications/plugins/asteroids/app.c +++ b/applications/plugins/asteroids/app.c @@ -3,6 +3,7 @@ #include #include +#include #include #include #include @@ -10,24 +11,23 @@ #include #include #include - -#ifndef PI -#define PI 3.14159265358979f -#endif +#include +#include #define TAG "Asteroids" // Used for logging #define DEBUG_MSG 1 #define SCREEN_XRES 128 #define SCREEN_YRES 64 #define GAME_START_LIVES 3 - -/* The game uses the OK button both to fire and to accelerate the ship. - * This makes it a lot more playable since the finger does not have to - * move between two keys. However it is important that the extra time the - * player needs to press the button to accelerate instead of just firing - * is precisely selected to provide a smooth experience. After a few - * attempts, it looks like 70 milliseconds is the right spot. */ -#define SHIP_ACCELERATION_KEYPRESS_TIME 70 +#define TTLBUL 30 /* Bullet time to live, in ticks. */ +#define MAXBUL 5 /* Max bullets on the screen. */ +#define MAXAST 32 /* Max asteroids on the screen. */ +#define SHIP_HIT_ANIMATION_LEN 15 +#define SAVING_DIRECTORY "/ext/apps_data/asteroids" +#define SAVING_FILENAME SAVING_DIRECTORY "/game_asteroids.save" +#ifndef PI +#define PI 3.14159265358979f +#endif /* ============================ Data structures ============================= */ @@ -36,7 +36,7 @@ typedef struct Ship { y, /* Ship y position. */ vx, /* x velocity. */ vy, /* y velocity. */ - rot; /* Current rotation. 2*PI full rotation. */ + rot; /* Current rotation. 2*PI full ortation. */ } Ship; typedef struct Bullet { @@ -51,21 +51,20 @@ typedef struct Asteroid { uint8_t shape_seed; /* Seed to give random shape. */ } Asteroid; -#define MAXBUL 10 /* Max bullets on the screen. */ -#define MAXAST 32 /* Max asteroids on the screen. */ -#define SHIP_HIT_ANIMATION_LEN 15 typedef struct AsteroidsApp { /* GUI */ Gui* gui; ViewPort* view_port; /* We just use a raw viewport and we render everything into the low level canvas. */ - FuriMessageQueue* event_queue; /* Key press events go here. */ + FuriMessageQueue* event_queue; /* Keypress events go here. */ /* Game state. */ int running; /* Once false exists the app. */ - bool gameover; /* Game over status. */ + bool gameover; /* Gameover status. */ uint32_t ticks; /* Game ticks. Increments at each refresh. */ uint32_t score; /* Game score. */ + uint32_t highscore; /* Highscore. Shown on Game Over Screen */ + bool is_new_highscore; /* Is the last score a new highscore? */ uint32_t lives; /* Number of lives in the current game. */ uint32_t ship_hit; /* When non zero, the ship was hit by an asteroid and we need to show an animation as long as @@ -90,10 +89,55 @@ typedef struct AsteroidsApp { bool fire; /* Short press detected: fire a bullet. */ } AsteroidsApp; -/* ============================== Prototypes ================================ */ +const NotificationSequence sequence_thrusters = { + &message_vibro_on, + &message_delay_10, + &message_vibro_off, + NULL, +}; + +const NotificationSequence sequence_brake = { + &message_vibro_on, + &message_delay_10, + &message_delay_1, + &message_delay_1, + &message_vibro_off, + NULL, +}; + +const NotificationSequence sequence_crash = { + &message_red_255, + + &message_vibro_on, + // &message_note_g5, // Play sound but currently disabled + &message_delay_25, + // &message_note_e5, + &message_vibro_off, + &message_sound_off, + NULL, +}; + +const NotificationSequence sequence_bullet_fired = { + &message_vibro_on, + // &message_note_g5, // Play sound but currently disabled. Need On/Off menu setting + &message_delay_10, + &message_delay_1, + &message_delay_1, + &message_delay_1, + &message_delay_1, + &message_delay_1, + + // &message_note_e5, + &message_vibro_off, + &message_sound_off, + NULL, +}; + +/* ============================== Prototyeps ================================ */ // Only functions called before their definition are here. - +bool load_game(AsteroidsApp* app); +void save_game(AsteroidsApp* app); void restart_game_after_gameover(AsteroidsApp* app); uint32_t key_pressed_time(AsteroidsApp* app, InputKey key); @@ -114,7 +158,7 @@ Poly ShipPoly = {{-3, 0, 3}, {-3, 6, -3}, 3}; Poly ShipFirePoly = {{-1.5, 0, 1.5}, {-3, -6, -3}, 3}; -/* Rotate the point of the polygon 'poly' and store the new rotated +/* Rotate the point of the poligon 'poly' and store the new rotated * polygon in 'rot'. The polygon is rotated by an angle 'a', with * center at 0,0. */ void rotate_poly(Poly* rot, Poly* poly, float a) { @@ -165,7 +209,7 @@ void draw_bullet(Canvas* const canvas, Bullet* b) { /* Draw an asteroid. The asteroid shapes is computed on the fly and * is not stored in a permanent shape structure. In order to generate * the shape, we use an initial fixed shape that we resize according - * to the asteroid size, perturbed according to the asteroid shape + * to the asteroid size, perturbate according to the asteroid shape * seed, and finally draw it rotated of the right amount. */ void draw_asteroid(Canvas* const canvas, Asteroid* ast) { Poly ap; @@ -241,8 +285,11 @@ void render_callback(Canvas* const canvas, void* ctx) { /* Draw ship, asteroids, bullets. */ draw_poly(canvas, &ShipPoly, app->ship.x, app->ship.y, app->ship.rot); - if(key_pressed_time(app, InputKeyOk) > SHIP_ACCELERATION_KEYPRESS_TIME) + + if(key_pressed_time(app, InputKeyUp) > 0) { + notification_message(furi_record_open(RECORD_NOTIFICATION), &sequence_thrusters); draw_poly(canvas, &ShipFirePoly, app->ship.x, app->ship.y, app->ship.rot); + } for(int j = 0; j < app->bullets_num; j++) draw_bullet(canvas, &app->bullets[j]); @@ -252,6 +299,30 @@ void render_callback(Canvas* const canvas, void* ctx) { if(app->gameover) { canvas_set_color(canvas, ColorBlack); canvas_set_font(canvas, FontPrimary); + + // TODO: if new highscore, display blinking "New High Score" + // Display High Score + if(app->is_new_highscore) { + canvas_draw_str(canvas, 22, 9, "New High Score!"); + } else { + canvas_draw_str(canvas, 36, 9, "High Score"); + } + + // Convert highscore to string + int length = snprintf(NULL, 0, "%lu", app->highscore); + char* str_high_score = malloc(length + 1); + snprintf(str_high_score, length + 1, "%lu", app->highscore); + + // Get length to center on screen + int nDigits = 0; + if(app->highscore > 0) { + nDigits = floor(log10(app->highscore)) + 1; + } + + // Draw highscore centered + canvas_draw_str(canvas, (SCREEN_XRES / 2) - (nDigits * 2), 20, str_high_score); + free(str_high_score); + canvas_draw_str(canvas, 28, 35, "GAME OVER"); canvas_set_font(canvas, FontSecondary); canvas_draw_str(canvas, 25, 50, "Press OK to restart"); @@ -295,6 +366,7 @@ bool objects_are_colliding(float x1, float y1, float r1, float x2, float y2, flo /* Create a new bullet headed in the same direction of the ship. */ void ship_fire_bullet(AsteroidsApp* app) { if(app->bullets_num == MAXBUL) return; + notification_message(furi_record_open(RECORD_NOTIFICATION), &sequence_bullet_fired); Bullet* b = &app->bullets[app->bullets_num]; b->x = app->ship.x; b->y = app->ship.y; @@ -316,7 +388,7 @@ void ship_fire_bullet(AsteroidsApp* app) { b->vx += app->ship.vx; b->vy += app->ship.vy; - b->ttl = 50; /* The bullet will disappear after N ticks. */ + b->ttl = TTLBUL; /* The bullet will disappear after N ticks. */ app->bullets_num++; } @@ -366,7 +438,7 @@ void remove_asteroid(AsteroidsApp* app, int id) { /* Called when an asteroid was reached by a bullet. The asteroid * hit is the one with the specified 'id'. */ void asteroid_was_hit(AsteroidsApp* app, int id) { - float sizelimit = 6; // Smaller than that, they disappear in one shot. + float sizelimit = 6; // Smaller than that polverize in one shot. Asteroid* a = &app->asteroids[id]; /* Asteroid is large enough to break into fragments. */ @@ -387,17 +459,19 @@ void asteroid_was_hit(AsteroidsApp* app, int id) { } } else { app->score++; + if(app->score > app->highscore) { + app->is_new_highscore = true; + app->highscore = app->score; // Show on Game Over Screen and future main menu + } } } -/* Set game over state. When in game-over mode, the game displays a - * game over text with a background of many asteroids floating around. */ +/* Set gameover state. When in game-over mode, the game displays a gameover + * text with a background of many asteroids floating around. */ void game_over(AsteroidsApp* app) { - restart_game_after_gameover(app); + if(app->is_new_highscore) save_game(app); // Save highscore but only on change app->gameover = true; - int asteroids = 8; - while(asteroids-- && add_asteroid(app) != NULL) - ; + app->lives = GAME_START_LIVES; // Show 3 lives in game over screen to match new game start } /* Function called when a collision between the asteroid and the @@ -422,16 +496,17 @@ void restart_game(AsteroidsApp* app) { app->bullets_num = 0; app->last_bullet_tick = 0; app->asteroids_num = 0; + app->ship_hit = 0; } -/* Called after game over to restart the game. This function +/* Called after gameover to restart the game. This function * also calls restart_game(). */ void restart_game_after_gameover(AsteroidsApp* app) { app->gameover = false; app->ticks = 0; app->score = 0; - app->ship_hit = 0; - app->lives = GAME_START_LIVES - 1; /* -1 to account for current one. */ + app->is_new_highscore = false; + app->lives = GAME_START_LIVES - 1; restart_game(app); } @@ -505,6 +580,7 @@ void game_tick(void* ctx) { * 1. Ship was hit, we frozen the game as long as ship_hit isn't zero * again, and show an animation of a rotating ship. */ if(app->ship_hit) { + notification_message(furi_record_open(RECORD_NOTIFICATION), &sequence_crash); app->ship.rot += 0.5; app->ship_hit--; view_port_update(app->view_port); @@ -515,7 +591,8 @@ void game_tick(void* ctx) { } else if(app->gameover) { /* 2. Game over. We need to update only background asteroids. In this * state the game just displays a GAME OVER text with the floating - * asteroids in background. */ + * asteroids in backgroud. */ + if(key_pressed_time(app, InputKeyOk) > 100) { restart_game_after_gameover(app); } @@ -524,13 +601,14 @@ void game_tick(void* ctx) { return; } - /* Handle key presses. */ + /* Handle keypresses. */ if(app->pressed[InputKeyLeft]) app->ship.rot -= .35; if(app->pressed[InputKeyRight]) app->ship.rot += .35; - if(key_pressed_time(app, InputKeyOk) > SHIP_ACCELERATION_KEYPRESS_TIME) { + if(app->pressed[InputKeyUp]) { app->ship.vx -= 0.5 * (float)sin(app->ship.rot); app->ship.vy += 0.5 * (float)cos(app->ship.rot); } else if(app->pressed[InputKeyDown]) { + notification_message(furi_record_open(RECORD_NOTIFICATION), &sequence_brake); app->ship.vx *= 0.75; app->ship.vy *= 0.75; } @@ -567,6 +645,41 @@ void game_tick(void* ctx) { /* ======================== Flipper specific code =========================== */ +bool load_game(AsteroidsApp* app) { + Storage* storage = furi_record_open(RECORD_STORAGE); + + File* file = storage_file_alloc(storage); + uint16_t bytes_readed = 0; + if(storage_file_open(file, SAVING_FILENAME, FSAM_READ, FSOM_OPEN_EXISTING)) { + bytes_readed = storage_file_read(file, app, sizeof(AsteroidsApp)); + } + storage_file_close(file); + storage_file_free(file); + + furi_record_close(RECORD_STORAGE); + + return bytes_readed == sizeof(AsteroidsApp); +} + +void save_game(AsteroidsApp* app) { + Storage* storage = furi_record_open(RECORD_STORAGE); + + if(storage_common_stat(storage, SAVING_DIRECTORY, NULL) == FSE_NOT_EXIST) { + if(!storage_simply_mkdir(storage, SAVING_DIRECTORY)) { + return; + } + } + + File* file = storage_file_alloc(storage); + if(storage_file_open(file, SAVING_FILENAME, FSAM_WRITE, FSOM_CREATE_ALWAYS)) { + storage_file_write(file, app, sizeof(AsteroidsApp)); + } + storage_file_close(file); + storage_file_free(file); + + furi_record_close(RECORD_STORAGE); +} + /* Here all we do is putting the events into the queue that will be handled * in the while() loop of the app entry point function. */ void input_callback(InputEvent* input_event, void* ctx) { @@ -579,6 +692,8 @@ void input_callback(InputEvent* input_event, void* ctx) { AsteroidsApp* asteroids_app_alloc() { AsteroidsApp* app = malloc(sizeof(AsteroidsApp)); + load_game(app); + app->gui = furi_record_open(RECORD_GUI); app->view_port = view_port_alloc(); view_port_draw_callback_set(app->view_port, render_callback, app); @@ -587,6 +702,7 @@ AsteroidsApp* asteroids_app_alloc() { app->event_queue = furi_message_queue_alloc(8, sizeof(InputEvent)); app->running = 1; /* Turns 0 when back is pressed. */ + restart_game_after_gameover(app); memset(app->pressed, 0, sizeof(app->pressed)); return app; @@ -617,12 +733,15 @@ uint32_t key_pressed_time(AsteroidsApp* app, InputKey key) { /* Handle keys interaction. */ void asteroids_update_keypress_state(AsteroidsApp* app, InputEvent input) { + // Allow Rapid fire + if(input.key == InputKeyOk) { + app->fire = true; + } + if(input.type == InputTypePress) { app->pressed[input.key] = furi_get_tick(); } else if(input.type == InputTypeRelease) { - uint32_t dur = key_pressed_time(app, input.key); app->pressed[input.key] = 0; - if(dur < 200 && input.key == InputKeyOk) app->fire = true; } } @@ -646,7 +765,9 @@ int32_t asteroids_app_entry(void* p) { /* Handle navigation here. Then handle view-specific inputs * in the view specific handling function. */ - if(input.type == InputTypeShort && input.key == InputKeyBack) { + if(input.type == InputTypeLong && input.key == InputKeyBack) { + // Save High Score even if player didn't finish game + if(app->is_new_highscore) save_game(app); // Save highscore but only on change app->running = 0; } else { asteroids_update_keypress_state(app, input); diff --git a/applications/plugins/clock_app/clock_app.c b/applications/plugins/clock_app/clock_app.c index 47b2ba8bdb..d2c178903d 100644 --- a/applications/plugins/clock_app/clock_app.c +++ b/applications/plugins/clock_app/clock_app.c @@ -39,11 +39,12 @@ static void clock_render_callback(Canvas* const canvas, void* ctx) { } else { bool pm = curr_dt.hour > 12; bool pm12 = curr_dt.hour >= 12; + bool am12 = curr_dt.hour == 0; snprintf( time_string, TIME_LEN, CLOCK_TIME_FORMAT, - pm ? curr_dt.hour - 12 : curr_dt.hour, + pm ? curr_dt.hour - 12 : (am12 ? 12 : curr_dt.hour), curr_dt.minute, curr_dt.second); @@ -237,4 +238,4 @@ int32_t clock_app(void* p) { free(plugin_state); return 0; -} \ No newline at end of file +} diff --git a/applications/plugins/dap_link/dap_link.c b/applications/plugins/dap_link/dap_link.c index 15f3ce7715..c46c687882 100644 --- a/applications/plugins/dap_link/dap_link.c +++ b/applications/plugins/dap_link/dap_link.c @@ -16,8 +16,6 @@ #include #include "DAP_Link_icons.h" -#include "../../settings/desktop_settings/desktop_settings_app.h" - /***************************************************************************/ /****************************** DAP COMMON *********************************/ /***************************************************************************/ @@ -484,37 +482,23 @@ DapConfig* dap_app_get_config(DapApp* app) { int32_t dap_link_app(void* p) { UNUSED(p); - DesktopSettings* settings = malloc(sizeof(DesktopSettings)); - DESKTOP_SETTINGS_LOAD(settings); if(furi_hal_usb_is_locked()) { DialogsApp* dialogs = furi_record_open(RECORD_DIALOGS); DialogMessage* message = dialog_message_alloc(); - if(settings->sfw_mode) { - dialog_message_set_header( - message, "Connection\nis active!", 3, 2, AlignLeft, AlignTop); - dialog_message_set_text( - message, - "Disconnect from\nPC or phone to\nuse this function.", - 3, - 30, - AlignLeft, - AlignTop); - } else { - dialog_message_set_header(message, "I am not\na whore!", 3, 2, AlignLeft, AlignTop); - dialog_message_set_text( - message, - "Pull out from\nPC or phone to\nuse me like this.", - 3, - 30, - AlignLeft, - AlignTop); - } + dialog_message_set_header( + message, "Connection\nis active!", 3, 2, AlignLeft, AlignTop); + dialog_message_set_text( + message, + "Disconnect from\nPC or phone to\nuse this function.", + 3, + 30, + AlignLeft, + AlignTop); dialog_message_set_icon(message, &I_ActiveConnection_50x64, 78, 0); dialog_message_show(dialogs, message); dialog_message_free(message); furi_record_close(RECORD_DIALOGS); - free(settings); return -1; } diff --git a/applications/plugins/dice/dice.c b/applications/plugins/dice/dice.c index 92fd09a389..61aa7b4f51 100644 --- a/applications/plugins/dice/dice.c +++ b/applications/plugins/dice/dice.c @@ -5,7 +5,6 @@ #include #include #include -#include "applications/settings/desktop_settings/desktop_settings_app.h" #define TAG "Dice Roller" @@ -22,7 +21,6 @@ typedef struct { typedef struct { FuriMutex* mutex; FuriMessageQueue* event_queue; - DesktopSettings* desktop_settings; FuriHalRtcDateTime datetime; uint8_t diceSelect; uint8_t diceQty; @@ -430,7 +428,6 @@ static void dice_state_init(DiceState* const state) { state->playerOneScore = 0; state->playerTwoScore = 0; state->letsRoll = false; - state->desktop_settings = malloc(sizeof(DesktopSettings)); } static void dice_tick(void* ctx) { @@ -470,7 +467,6 @@ int32_t dice_app(void* p) { return 255; } - DESKTOP_SETTINGS_LOAD(plugin_state->desktop_settings); ViewPort* view_port = view_port_alloc(); view_port_draw_callback_set(view_port, dice_render_callback, plugin_state); @@ -510,11 +506,7 @@ int32_t dice_app(void* p) { } else if(plugin_state->diceSelect == 20) { plugin_state->diceSelect = 100; } else if(plugin_state->diceSelect == 100) { - if(plugin_state->desktop_settings->is_sfwmode) { - plugin_state->diceSelect = 231; - } else { - plugin_state->diceSelect = 230; - } + plugin_state->diceSelect = 230; } else if(plugin_state->diceSelect == 230) { plugin_state->playerOneScore = 0; plugin_state->playerTwoScore = 0; @@ -524,11 +516,7 @@ int32_t dice_app(void* p) { } else if(plugin_state->diceSelect == 229) { plugin_state->diceSelect = 228; } else if(plugin_state->diceSelect == 228) { - if(plugin_state->desktop_settings->is_sfwmode) { - plugin_state->diceSelect = 59; - } else { - plugin_state->diceSelect = 232; - } + plugin_state->diceSelect = 232; } else if(plugin_state->diceSelect == 232) { plugin_state->diceSelect = 59; } else if(plugin_state->diceSelect == 59) { @@ -571,7 +559,6 @@ int32_t dice_app(void* p) { view_port_free(view_port); furi_message_queue_free(plugin_state->event_queue); furi_mutex_free(plugin_state->mutex); - free(plugin_state->desktop_settings); free(plugin_state); return 0; } diff --git a/applications/plugins/orgasmotron/orgasmotron.c b/applications/plugins/orgasmotron/orgasmotron.c index 814a9e26d7..b28f392f53 100644 --- a/applications/plugins/orgasmotron/orgasmotron.c +++ b/applications/plugins/orgasmotron/orgasmotron.c @@ -5,15 +5,23 @@ #include #include +typedef struct { + int mode; +} PluginState; + void vibro_test_draw_callback(Canvas* canvas, void* ctx) { UNUSED(ctx); canvas_clear(canvas); canvas_set_font(canvas, FontPrimary); - canvas_draw_str(canvas, 2, 10, "Vibro application"); + canvas_draw_str(canvas, 2, 10, "Vibro Modes"); + canvas_set_font(canvas, FontSecondary); + canvas_draw_str(canvas, 2, 22, "LEFT: strong / RIGHT: Soft"); canvas_set_font(canvas, FontSecondary); - canvas_draw_str(canvas, 2, 22, "Press OK turns on vibro"); + canvas_draw_str(canvas, 2, 34, "UP: Pulsed"); canvas_set_font(canvas, FontSecondary); - canvas_draw_str(canvas, 2, 34, "Press LEFT turns off vibro"); + canvas_draw_str(canvas, 2, 46, "DOWN Pleasure combo"); + canvas_set_font(canvas, FontSecondary); + canvas_draw_str(canvas, 2, 58, "OK: Pause"); } void vibro_test_input_callback(InputEvent* input_event, void* ctx) { @@ -22,10 +30,22 @@ void vibro_test_input_callback(InputEvent* input_event, void* ctx) { furi_message_queue_put(event_queue, input_event, FuriWaitForever); } +void delay(int milliseconds) { + furi_thread_flags_wait(0, FuriFlagWaitAny, milliseconds); +} + int32_t orgasmotron_app(void* p) { UNUSED(p); FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(InputEvent)); + PluginState* plugin_state = malloc(sizeof(PluginState)); + ValueMutex state_mutex; + if (!init_mutex(&state_mutex, plugin_state, sizeof(PluginState))) { + FURI_LOG_E("Orgasmatron", "cannot create mutex\r\n"); + free(plugin_state); + return 255; + } + // Configure view port ViewPort* view_port = view_port_alloc(); view_port_draw_callback_set(view_port, vibro_test_draw_callback, NULL); @@ -38,31 +58,76 @@ int32_t orgasmotron_app(void* p) { NotificationApp* notification = furi_record_open(RECORD_NOTIFICATION); InputEvent event; - - while(furi_message_queue_get(event_queue, &event, FuriWaitForever) == FuriStatusOk) { - if(event.type == InputTypeShort && event.key == InputKeyBack) { + //int mode = 0; + bool processing = true; + //while(furi_message_queue_get(event_queue, &event, FuriWaitForever) == FuriStatusOk) { + while (processing) { + FuriStatus event_status = furi_message_queue_get(event_queue, &event, 100); + PluginState* plugin_state = (PluginState*)acquire_mutex_block(&state_mutex); + if (event_status == FuriStatusOk) { + if(event.key == InputKeyBack && event.type == InputTypeShort) { + //Exit Application + notification_message(notification, &sequence_reset_vibro); + notification_message(notification, &sequence_reset_green); + plugin_state->mode = 0; + processing = false; + //break; + } + if(event.key == InputKeyOk && (event.type == InputTypePress || event.type == InputTypeRelease)) { + plugin_state->mode = 0; + } + if(event.key == InputKeyLeft && (event.type == InputTypePress || event.type == InputTypeRelease)) { + plugin_state->mode = 1; + } + if(event.key == InputKeyRight && (event.type == InputTypePress || event.type == InputTypeRelease)) { + plugin_state->mode = 3; + } + if(event.key == InputKeyUp && (event.type == InputTypePress || event.type == InputTypeRelease)) { + plugin_state->mode = 2; + } + if(event.key == InputKeyDown && (event.type == InputTypePress || event.type == InputTypeRelease)) { + plugin_state->mode = 4; + } + } + + if (plugin_state->mode == 0) { + //Stop Vibration notification_message(notification, &sequence_reset_vibro); notification_message(notification, &sequence_reset_green); - break; - } - if(event.key == InputKeyOk) { - if(event.type == InputTypePress) { + } else if (plugin_state->mode == 1) { + //Full power + notification_message(notification, &sequence_set_vibro_on); + notification_message(notification, &sequence_set_green_255); + } else if (plugin_state->mode == 2) { + //Pulsed Vibration + notification_message(notification, &sequence_set_vibro_on); + notification_message(notification, &sequence_set_green_255); + delay(100); + notification_message(notification, &sequence_reset_vibro); + } else if (plugin_state->mode == 3) { + //Soft power + notification_message(notification, &sequence_set_vibro_on); + notification_message(notification, &sequence_set_green_255); + delay(50); + notification_message(notification, &sequence_reset_vibro); + } else if (plugin_state->mode == 4) { + //Special Sequence + for (int i = 0;i < 15;i++) { notification_message(notification, &sequence_set_vibro_on); notification_message(notification, &sequence_set_green_255); - } else if(event.type == InputTypeRelease) { + delay(50); + notification_message(notification, &sequence_reset_vibro); + delay(50); + } + for (int i = 0;i < 2;i++) { notification_message(notification, &sequence_set_vibro_on); notification_message(notification, &sequence_set_green_255); - } - } - if(event.key == InputKeyLeft) { - if(event.type == InputTypePress) { + delay(400); notification_message(notification, &sequence_reset_vibro); - notification_message(notification, &sequence_reset_green); - } else if(event.type == InputTypeRelease) { - notification_message(notification, &sequence_reset_vibro); - notification_message(notification, &sequence_reset_green); + delay(50); } } + release_mutex(&state_mutex, plugin_state); } gui_remove_view_port(gui, view_port); view_port_free(view_port); @@ -70,6 +135,7 @@ int32_t orgasmotron_app(void* p) { furi_record_close(RECORD_NOTIFICATION); furi_record_close(RECORD_GUI); + delete_mutex(&state_mutex); return 0; } \ No newline at end of file diff --git a/applications/plugins/pocsag_pager/images/Scanning_123x52.png b/applications/plugins/pocsag_pager/images/Scanning_123x52.png index a48c5330e8..ec785948d0 100644 Binary files a/applications/plugins/pocsag_pager/images/Scanning_123x52.png and b/applications/plugins/pocsag_pager/images/Scanning_123x52.png differ diff --git a/applications/plugins/pocsag_pager/images/Scanning_123x52_sfw.png b/applications/plugins/pocsag_pager/images/Scanning_123x52_sfw.png deleted file mode 100644 index ec785948d0..0000000000 Binary files a/applications/plugins/pocsag_pager/images/Scanning_123x52_sfw.png and /dev/null differ diff --git a/applications/plugins/pocsag_pager/images/WarningDolphin_45x42.png b/applications/plugins/pocsag_pager/images/WarningDolphin_45x42.png index db225de36f..d766ffbb44 100644 Binary files a/applications/plugins/pocsag_pager/images/WarningDolphin_45x42.png and b/applications/plugins/pocsag_pager/images/WarningDolphin_45x42.png differ diff --git a/applications/plugins/pocsag_pager/images/WarningDolphin_45x42_sfw.png b/applications/plugins/pocsag_pager/images/WarningDolphin_45x42_sfw.png deleted file mode 100644 index d766ffbb44..0000000000 Binary files a/applications/plugins/pocsag_pager/images/WarningDolphin_45x42_sfw.png and /dev/null differ diff --git a/applications/plugins/pocsag_pager/views/pocsag_pager_receiver.c b/applications/plugins/pocsag_pager/views/pocsag_pager_receiver.c index c452e5fe9f..972c8dafb3 100644 --- a/applications/plugins/pocsag_pager/views/pocsag_pager_receiver.c +++ b/applications/plugins/pocsag_pager/views/pocsag_pager_receiver.c @@ -7,8 +7,6 @@ #include #include -#include "../../../settings/desktop_settings/desktop_settings_app.h" - #define FRAME_HEIGHT 12 #define MAX_LEN_PX 112 #define MENU_ITEMS 4u @@ -181,9 +179,6 @@ void pcsg_view_receiver_draw(Canvas* canvas, PCSGReceiverModel* model) { FuriString* str_buff; str_buff = furi_string_alloc(); - DesktopSettings* settings = malloc(sizeof(DesktopSettings)); - DESKTOP_SETTINGS_LOAD(settings); - PCSGReceiverMenuItem* item_menu; for(size_t i = 0; i < MIN(model->history_item, MENU_ITEMS); ++i) { @@ -209,11 +204,7 @@ void pcsg_view_receiver_draw(Canvas* canvas, PCSGReceiverModel* model) { canvas_set_color(canvas, ColorBlack); if(model->history_item == 0) { - if(settings->sfw_mode) { - canvas_draw_icon(canvas, 0, 0, &I_Scanning_123x52_sfw); - } else { - canvas_draw_icon(canvas, 0, 0, &I_Scanning_123x52); - } + canvas_draw_icon(canvas, 0, 0, &I_Scanning_123x52); canvas_set_font(canvas, FontPrimary); canvas_draw_str(canvas, 63, 46, "Scanning..."); canvas_draw_line(canvas, 46, 51, 125, 51); @@ -235,11 +226,7 @@ void pcsg_view_receiver_draw(Canvas* canvas, PCSGReceiverModel* model) { canvas_draw_icon(canvas, 65, 42, &I_Pin_back_arrow_10x8); canvas_draw_icon(canvas, 80, 42, &I_Pin_back_arrow_10x8); canvas_draw_icon(canvas, 95, 42, &I_Pin_back_arrow_10x8); - if(settings->sfw_mode) { - canvas_draw_icon(canvas, 16, 13, &I_WarningDolphin_45x42_sfw); - } else { - canvas_draw_icon(canvas, 16, 13, &I_WarningDolphin_45x42); - } + canvas_draw_icon(canvas, 16, 13, &I_WarningDolphin_45x42); canvas_draw_dot(canvas, 17, 61); break; case PCSGReceiverBarShowUnlock: @@ -252,7 +239,6 @@ void pcsg_view_receiver_draw(Canvas* canvas, PCSGReceiverModel* model) { canvas_draw_str(canvas, 96, 62, furi_string_get_cstr(model->history_stat_str)); break; } - free(settings); } static void pcsg_view_receiver_timer_callback(void* context) { diff --git a/applications/plugins/protoview/README.md b/applications/plugins/protoview/README.md index a12aec979b..71083cdef9 100644 --- a/applications/plugins/protoview/README.md +++ b/applications/plugins/protoview/README.md @@ -1,17 +1,15 @@ -ProtoView is a digital signal detection and visualization tool for the -[Flipper Zero](https://flipperzero.one/). The Flipper is able to identify -a great deal of RF protocols, however when the exact protocol is not -implemented (and there are many proprietary ones, such as the ones of -the car keys), the curious person is left wondering what the device is -sending at all. Using ProtoView she or he can visualize the high and low pulses -like in the example image below (showing a Volkswagen key in 2FSK): +ProtoView is a digital signal detection, visualization, editing and reply tool for the [Flipper Zero](https://flipperzero.one/). The Flipper default application, called Subghz, is able to identify certain RF protocols, but when the exact protocol is not implemented (and there are many undocumented and unimplemented ones, such as the ones in use in TPMS systems, car keys and many others), the curious person is left wondering what the device is sending at all. Using ProtoView she or he can visualize the high and low pulses like in the example image below (showing a TPMS signal produced by a Renault tire): ![ProtoView screenshot raw signal](/images/protoview_1.jpg) This is often enough to make an initial idea about the encoding used -and if the selected modulation is correct. +and if the selected modulation is correct. For example, in the signal above +you can see a set of regular pulses and gaps used for synchronization, and then +a sequence of bits encoded in [Manchester](https://en.wikipedia.org/wiki/Manchester_code) line code. If you study these things for five minutes, you'll find yourself able to decode the bits with naked eyes. -Other than that, ProtoView is able to decode a few interesting protocols: +## Decoding capabilities + +Other than showing the raw signal, ProtoView is able to decode a few interesting protocols: * TPMS sensors: Renault, Toyota, Schrader, Citroen, Ford. * Microchip HSC200/300/301 Keeloq protocol. @@ -23,25 +21,39 @@ Other than that, ProtoView is able to decode a few interesting protocols: The app implements a framework that makes adding and experimenting with new protocols very simple. Check the `protocols` directory to see how the -API works. +API works, or read the full documentation at the end of this `README` file. +The gist of it is that the decoder receives the signal already converted into +a bitmap, where each bit represents a short pulse duration. Then there are +functions to seek specific sync/preamble sequences inside the bitmap, to decode +from different line codes, to compute checksums and so forth. + +## Signals transmission capabilities + +Once ProtoView decodes a given message, it is able to *resample* it +in pulses and gaps of the theoretical duration, and send the signal again +via the Flipper TX capabilities. The captured signal can be sent +to different frequencies and modulations than the ones it was captured +from. + +For selected protocols, that implement the message creation methods, +ProtoView is also able to edit the message received, modify fields, +and finally re-detect the new produced signal and resend it. Signals +can also be produced from scratch, by setting all the fields to appropriate +values. -The secondary goal of ProtoView is to provide a somewhat-documented application -for the Flipper (even if ProtoView is a pretty atypical application: doesn't make use of the standard widgets and other abstractions provded by the framework). -Many apps dealing with the *subghz subsystem* (the Flipper -abstraction to work with the [CC1101 chip](https://www.ti.com/product/CC1101)) -tend to be complicated and completely undocumented. This is unfortunately -true for the firmware of the device itself. It's a shame because especially -in the case of code that talks with hardware peripherals there are tons -of assumptions and hard-gained lessons that can [only be captured by comments and are in the code only implicitly](http://antirez.com/news/124). +## A well-documented app for the Flipper + +The secondary goal of ProtoView is to provide a well-documented application for the Flipper (even if ProtoView is a pretty atypical application: it doesn't make use of the standard widgets and other abstractions provided by the framework). +Most apps dealing with the *subghz subsystem* of the Flipper (the abstraction used to work with the [CC1101 chip](https://www.ti.com/product/CC1101)) tend to be complicated and completely undocumented. +Unfortunately, this is also true for the firmware of the device. +It's a shame, because especially in the case of code that talks with hardware peripherals there are tons of assumptions and hard-gained lessons that can [only be captured by comments and are in the code only implicitly](http://antirez.com/news/124). However, the Flipper firmware source code is well written even if it -lacks comments and documentation, so it is possible to make some ideas of -how things work just grepping inside. +lacks comments and documentation (and sometimes makes use of abstractions more convoluted than needed), so it is possible to make some ideas of how things work just grepping inside. In order to develop this application, I ended reading most parts of the firmware of the device. -# Detection algorithm +## Detection algorithm -In order to show unknown signals, the application attempts to understand if -the samples obtained by the Flipper API (a series of pulses that are high +In order to detect and show unknown signals, the application attempts to understand if the samples obtained by the Flipper API (a series of pulses that are high or low, and with different duration in microseconds) look like belonging to a legitimate signal, and aren't just noise. @@ -49,25 +61,34 @@ We can't make assumptions about the encoding and the data rate of the communication, so we use a simple but relatively effective algorithm. As we check the signal, we try to detect long parts of it that are composed of pulses roughly classifiable into -a maximum of three different classes of lengths, plus or minus 10%. Most -encodings are somewhat self-clocked, so they tend to have just two or +a maximum of three different duration classes, plus or minus a given percentage. +Most encodings are somewhat self-clocked, so they tend to have just two or three classes of pulse lengths. -However often pulses of the same theoretical +However, often, pulses of the same theoretical length have slightly different lengths in the case of high and low level -(RF on or off), so we classify them separately for robustness. +(RF on or off), so the detector classifies them separately for robustness. + +Once the raw signal is detected, the registered protocol decoders are called +against it, in the hope some of the decoders will make sense of the signal. # Usage -The application shows the longest coherent signal detected so far. +In the main screen, the application shows the longest coherent signal detected so far. The user can switch to other views pressing the LEFT and RIGHT keys. The BACK key will return back to the main screen. Long pressing BACK will quit the application. + +## Main raw signal screen -* The OK button resets the current signal. -* The UP and DOWN buttons change the scale. Default is 100us per pixel. -* The LEFT and RIGHT buttons switch to settings. +* A long press of the OK button resets the current signal, in order to capture a new one. +* The UP and DOWN buttons change the scale. Default is 100us per pixel, but it will be adapted to the signal just captured. +* A long press of the LEFT and RIGHT keys will pan the signal, to see what was transmitted before/after the current shown range. +* A short press to OK will recenter the signal and set the scale back to the default for the specific pulse duration detected. Under the detected sequence, you will see a small triangle marking a specific sample. This mark means that the sequence looked coherent up -to that point, and starting from there it could be just noise. +to that point, and starting from there it could be just noise. However the +signal decoders will not get just up to this point, but will get more: +sometimes the low level detector can't make sense of a signal that the +protocol-specific decoder can understand fully. If the protocol is decoded, the bottom-left corner of the screen will show the name of the protocol, and going in the next screen @@ -81,12 +102,47 @@ and could actually be `1000000/this-number*N` with `N > 2` (here 1000000 is the number of microseconds in one second, and N is the number of clock cycles needed to represent a bit). -Things to investigate: +## Info screen + +If a signal was detected, the info view will show the details about the signal. If the signal has more data that a single screen can fit, pressing OK will show the next fields. Pressing DOWN will go to a sub-view with an oscilloscope-alike representation of the signal, from there you can: + +1. Resend the signal, by pressing OK. +2. Save the signal as `.sub` file, by long pressing OK. + +When resending, you can select a different frequency and modulation if you +wish. + +## Frequency and modulation screen + +In this view you can just set the frequency and modulation you want to use. +There are special modulations for TPMS signals: they need an higher data +rate. * Many cheap remotes (gate openers, remotes, ...) are on the 433.92Mhz or nearby and use OOK modulation. * Weather stations are often too in the 433.92Mhz OOK. * For car keys, try 433.92 OOK650 and 868.35 Mhz in OOK or 2FSK. -* For TPMS try 433.92 in TPMS modulation (FSK optimized for these signals). +* For TPMS try 433.92 in TPMS1 or TPMS2 modulations (FSK and OOK custom modulations optimized for these signals, that have a relatively high data rate). + +## Signal creator + +In this view, you can do two things: + +1. Select one of the protocols supporting message creation, and create a signal from scratch. +2. If there is already a detected signal, you can modify the signal. + +This is how it works: + +1. Select one of the protocols (the one of the currently detected signal will be already provided as default, if any, and if it supports message creation). +2. Fill the fields. Use LEFT and RIGHT to change the values of integers, or just press OK and enter the new value with the Fliper keyboard widget. +3. When you are done, long press OK to build the message. Then press BACK in order to see it. +4. Go to the INFO view, and then DOWN to the signal sending/saving subview in order to send or save it. + +## Direct sampling screen + +This final screen shows in real time the high and low level that the Flipper +RF chip, the CC1101, is receiving. This will makes very easy to understand +if a given frequency is targeted by something other than noise. This mode is +fun to watch, resembling an old CRT TV set. # Installing the app from source @@ -113,6 +169,107 @@ to use the Android (or other) application to upload the file, you can just take out the SD card, insert it in your computer, copy the fine into `apps/Tools`, and that's it. +# Protocols decoders API + +Writing a protocol decoder is not hard, and requires to write three +different methods. + +1. `decode()`. This is mandatory, and is used in order to turn a known signal into a set of fields containing certain informations. For instance for a thermometer sending data via RF, a raw message will be decoded into fields like temperature, humidity, station ID and so forth. +2. `get_fields()`. Optional, only needed if the protocol supports creating and editing signals. This method just returns the fields names, types and defaults. The app will use this list in order to allow the user to set values. The populated fields will be passed to the `build_message()` method later. +3. `build_message()`. This method gets a set of fields representing the parameters of the protocol, as set by the user, and will create a low level signal composed of pulses and gaps of specific durations. + +## `decode()` method + + bool decode(uint8_t *bits, uint32_t numbytes, uint32_t numbits, ProtoViewMsgInfo *info); + +The method gets a bitmap `bits` long `numbytes` bytes but actually containing `bumbits` valid bits. Each bit represents a pulse of gap of the duration of the shortest time detected in the protocol (this is often called *te*, in the RF protocols jargon). So, for instance, if a signal is composed of pulses and gaps of around 500 and 1000 microseconds, each bit in the bitmap will represent 500 microseconds. + +Continuing with the example above, if the received signal was composed of a 1000 microseconds gap, then a 500 microsecond pulse, then a 500 microsecond gap and finally a 1000 microseconds pulse, its bitmap representation will be: + + 001011 + +To access the bitmap, the decoder can use the following API: + + bool bitmap_get(uint8_t *b, uint32_t blen, uint32_t bitpos); + +The `blen` parameter will be set to what the decode method gets +as `numbytes`, and is used to prevent overflows. This way if `bitpos` +is out of range, nothing bad happens. + +There are function to match and seek specific patterns inside the signal: + + bool bitmap_match_bits(uint8_t *b, uint32_t blen, uint32_t bitpos, const char *bits); + uint32_t bitmap_seek_bits(uint8_t *b, uint32_t blen, uint32_t startpos, uint32_t maxbits, const char *bits); + +Finally, there are functions to convert from different line codes: + + uint32_t convert_from_line_code(uint8_t *buf, uint64_t buflen, uint8_t *bits, uint32_t len, uint32_t offset, const char *zero_pattern, const char *one_pattern); + uint32_t convert_from_diff_manchester(uint8_t *buf, uint64_t buflen, uint8_t *bits, uint32_t len, uint32_t off, bool previous); + +This method can also access the short pulse duration by inspecting the +`info->short_pulse_dur` field (in microseconds). + +Please check the `b4b1.c` file for an easy to understand example of the decoder implementation. + +If the decoder actually detected a message, it will return `true` and will return a set of fields, like thata: + + fieldset_add_bytes(info->fieldset,"id",d,5); + fieldset_add_uint(info->fieldset,"button",d[2]&0xf,4); + +## `get_fields()` method. + + static void get_fields(ProtoViewFieldSet *fieldset); + +This method will be basically a copy of the final part of `decode()`, as +it also needs to return the set of fields this protocol is composed of. +However instead of returning the values of an actual decoded message, it +will just provide their default values for the signal creator view. + +Note that the `build_message()` method is guaranteed to receive the +same exact fields in the same exact order. + +## `build_message()` method. + + void build_message(RawSamplesBuffer *samples, ProtoViewFieldSet *fs); + +This method is responsible of creating a signal from scratch, by +appending gaps and pulses of the specific duration into `samples` +using the following API: + + raw_samples_add(RawSamplesBuffer *samples, bool level, uint32_t duration); + +Level can be true (pules) or false (gap). Duration is in microseconds. +The method receives a set of fields in `fs`. Each field is accessible +directly accessing `fs->fields[... field index ...]`, where the field +index is 0, 1, 2, ... in the same order as `get_fields()` returned the +fields. + +For now, you can access the fields in the raw way, by getting the +values directly from the data structure representing each field: + +``` +typedef struct { + ProtoViewFieldType type; + uint32_t len; // Depends on type: + // Bits for integers (signed,unsigned,binary,hex). + // Number of characters for strings. + // Number of nibbles for bytes (1 for each 4 bits). + // Number of digits after dot for floats. + char *name; // Field name. + union { + char *str; // String type. + int64_t value; // Signed integer type. + uint64_t uvalue; // Unsigned integer type. + uint8_t *bytes; // Raw bytes type. + float fvalue; // Float type. + }; +} ProtoViewField; + +``` + +However later the app will likely provide a set of macros to do it +in a more future-proof way. + # License The code is released under the BSD license. diff --git a/applications/plugins/protoview/TODO b/applications/plugins/protoview/TODO deleted file mode 100644 index feb7b0743e..0000000000 --- a/applications/plugins/protoview/TODO +++ /dev/null @@ -1,14 +0,0 @@ -Core improvements -================= - -- Decoders should declare the short pulse duration range, so that - only matching decoders will be called. This may also be useful for - modulations. If a signal is only OOK, does not make much sense to - call it for samples obtained in FSK. -- More protocols, especially TPMS and other stuff not supported right now - by the Flipper. -- CC1101 synchronous mode with protocol hopping? -- Protocols decoded can register actions, for instance to generate - sub files with modified signal and so forth. -- Optimize memory usage storing raw samples in a bitfield: 15 bits - duration, 1 bit level. diff --git a/applications/plugins/protoview/app.c b/applications/plugins/protoview/app.c index ea4e366b8d..f16457e555 100644 --- a/applications/plugins/protoview/app.c +++ b/applications/plugins/protoview/app.c @@ -57,8 +57,12 @@ static void render_callback(Canvas *const canvas, void *ctx) { case ViewModulationSettings: render_view_settings(canvas,app); break; case ViewDirectSampling: render_view_direct_sampling(canvas,app); break; - case ViewLast: furi_crash(TAG " ViewLast selected"); break; + case ViewBuildMessage: render_view_build_message(canvas,app); break; + default: furi_crash(TAG "Invalid view selected"); break; } + + /* Draw the alert box if set. */ + ui_draw_alert_if_needed(canvas, app); } /* Here all we do is putting the events into the queue that will be handled @@ -69,32 +73,53 @@ static void input_callback(InputEvent* input_event, void* ctx) furi_message_queue_put(app->event_queue,input_event,FuriWaitForever); } - /* Called to switch view (when left/right is pressed). Handles * changing the current view ID and calling the enter/exit view - * callbacks if needed. */ -static void app_switch_view(ProtoViewApp *app, SwitchViewDirection dir) { + * callbacks if needed. + * + * The 'switchto' parameter can be the identifier of a view, or the + * special views ViewGoNext and ViewGoPrev in order to move to + * the logical next/prev view. */ +static void app_switch_view(ProtoViewApp *app, ProtoViewCurrentView switchto) { + /* Switch to the specified view. */ ProtoViewCurrentView old = app->current_view; - if (dir == AppNextView) { + if (switchto == ViewGoNext) { app->current_view++; if (app->current_view == ViewLast) app->current_view = 0; - } else if (dir == AppPrevView) { + } else if (switchto == ViewGoPrev) { if (app->current_view == 0) app->current_view = ViewLast-1; else app->current_view--; + } else { + app->current_view = switchto; } ProtoViewCurrentView new = app->current_view; + /* Set the current subview of the view we just left to zero. This is + * the main subview of the old view. When re re-enter the view we are + * lefting, we want to see the main thing again. */ + app->current_subview[old] = 0; + + /* Reset the view private data each time, before calling the enter/exit + * callbacks that may want to setup some state. */ + memset(app->view_privdata,0,PROTOVIEW_VIEW_PRIVDATA_LEN); + /* Call the enter/exit view callbacks if needed. */ if (old == ViewDirectSampling) view_exit_direct_sampling(app); if (new == ViewDirectSampling) view_enter_direct_sampling(app); + if (old == ViewBuildMessage) view_exit_build_message(app); + if (new == ViewBuildMessage) view_enter_build_message(app); + if (old == ViewInfo) view_exit_info(app); + /* The frequency/modulation settings are actually a single view: * as long as the user stays between the two modes of this view we * don't need to call the exit-view callback. */ if ((old == ViewFrequencySettings && new != ViewModulationSettings) || (old == ViewModulationSettings && new != ViewFrequencySettings)) view_exit_settings(app); + + ui_dismiss_alert(app); } /* Allocate the application state and initialize a number of stuff. @@ -112,13 +137,21 @@ ProtoViewApp* protoview_app_alloc() { // GUI app->gui = furi_record_open(RECORD_GUI); + app->notification = furi_record_open(RECORD_NOTIFICATION); app->view_port = view_port_alloc(); view_port_draw_callback_set(app->view_port, render_callback, app); view_port_input_callback_set(app->view_port, input_callback, app); gui_add_view_port(app->gui, app->view_port, GuiLayerFullscreen); app->event_queue = furi_message_queue_alloc(8, sizeof(InputEvent)); + app->view_dispatcher = NULL; + app->text_input = NULL; + app->show_text_input = false; + app->alert_dismiss_time = 0; app->current_view = ViewRawPulses; + for (int j = 0; j < ViewLast; j++) app->current_subview[j] = 0; app->direct_sampling_enabled = false; + app->view_privdata = malloc(PROTOVIEW_VIEW_PRIVDATA_LEN); + memset(app->view_privdata,0,PROTOVIEW_VIEW_PRIVDATA_LEN); // Signal found and visualization defaults app->signal_bestlen = 0; @@ -126,8 +159,9 @@ ProtoViewApp* protoview_app_alloc() { app->signal_decoded = false; app->us_scale = PROTOVIEW_RAW_VIEW_DEFAULT_SCALE; app->signal_offset = 0; + app->msg_info = NULL; - //init Worker & Protocol + // Init Worker & Protocol app->txrx = malloc(sizeof(ProtoViewTxRx)); /* Setup rx worker and environment. */ @@ -168,7 +202,7 @@ ProtoViewApp* protoview_app_alloc() { void protoview_app_free(ProtoViewApp *app) { furi_assert(app); - // Put CC1101 on sleep. + // Put CC1101 on sleep, this also restores charging. radio_sleep(app); // View related. @@ -176,6 +210,7 @@ void protoview_app_free(ProtoViewApp *app) { gui_remove_view_port(app->gui, app->view_port); view_port_free(app->view_port); furi_record_close(RECORD_GUI); + furi_record_close(RECORD_NOTIFICATION); furi_message_queue_free(app->event_queue); app->gui = NULL; @@ -217,9 +252,25 @@ static void timer_callback(void *ctx) { } if (delta < RawSamples->total/2) return; app->signal_last_scan_idx = RawSamples->idx; - scan_for_signal(app); + scan_for_signal(app,RawSamples); } +/* This is the navigation callback we use in the view dispatcher used + * to display the "text input" widget, that is the keyboard to get text. + * The text input view is implemented to ignore the "back" short press, + * so the event is not consumed and is handled by the view dispatcher. + * However the view dispatcher implementation has the strange behavior that + * if no navigation callback is set, it will not stop when handling back. + * + * We just need a dummy callback returning false. We believe the + * implementation should be changed and if no callback is set, it should be + * the same as returning false. */ +static bool keyboard_view_dispatcher_navigation_callback(void *ctx) { + UNUSED(ctx); + return false; +} + +/* App entry point, as specified in application.fam. */ int32_t protoview_app_entry(void* p) { UNUSED(p); ProtoViewApp *app = protoview_app_alloc(); @@ -249,18 +300,30 @@ int32_t protoview_app_entry(void* p) { if (input.type == InputTypeShort && input.key == InputKeyBack) { - /* Exit the app. */ + if (app->current_view != ViewRawPulses) { + /* If this is not the main app view, go there. */ + app_switch_view(app,ViewRawPulses); + } else { + /* If we are in the main app view, warn the user + * they needs to long press to really quit. */ + ui_show_alert(app,"Long press to exit",1000); + } + } else if (input.type == InputTypeLong && + input.key == InputKeyBack) + { app->running = 0; } else if (input.type == InputTypeShort && - input.key == InputKeyRight) + input.key == InputKeyRight && + ui_get_current_subview(app) == 0) { /* Go to the next view. */ - app_switch_view(app,AppNextView); + app_switch_view(app,ViewGoNext); } else if (input.type == InputTypeShort && - input.key == InputKeyLeft) + input.key == InputKeyLeft && + ui_get_current_subview(app) == 0) { /* Go to the previous view. */ - app_switch_view(app,AppPrevView); + app_switch_view(app,ViewGoPrev); } else { /* This is where we pass the control to the currently * active view input processing. */ @@ -278,7 +341,10 @@ int32_t protoview_app_entry(void* p) { case ViewDirectSampling: process_input_direct_sampling(app,input); break; - case ViewLast: furi_crash(TAG " ViewLast selected"); break; + case ViewBuildMessage: + process_input_build_message(app,input); + break; + default: furi_crash(TAG "Invalid view selected"); break; } } } else { @@ -289,7 +355,54 @@ int32_t protoview_app_entry(void* p) { if (!(c % 20)) FURI_LOG_E(TAG, "Loop timeout"); } } - view_port_update(app->view_port); + if (app->show_text_input) { + /* Remove our viewport: we need to use a view dispatcher + * in order to show the standard Flipper keyboard. */ + gui_remove_view_port(app->gui, app->view_port); + + /* Allocate a view dispatcher, add a text input view to it, + * and activate it. */ + app->view_dispatcher = view_dispatcher_alloc(); + view_dispatcher_enable_queue(app->view_dispatcher); + /* We need to set a navigation callback for the view dispatcher + * otherwise when the user presses back on the keyboard to + * abort, the dispatcher will not stop. */ + view_dispatcher_set_navigation_event_callback( + app->view_dispatcher, + keyboard_view_dispatcher_navigation_callback); + app->text_input = text_input_alloc(); + view_dispatcher_set_event_callback_context(app->view_dispatcher,app); + view_dispatcher_add_view(app->view_dispatcher, 0, text_input_get_view(app->text_input)); + view_dispatcher_switch_to_view(app->view_dispatcher, 0); + + /* Setup the text input view. The different parameters are set + * in the app structure by the view that wanted to show the + * input text. The callback, buffer and buffer len must be set. */ + text_input_set_header_text(app->text_input, "Save signal filename"); + text_input_set_result_callback( + app->text_input, + app->text_input_done_callback, + app, + app->text_input_buffer, + app->text_input_buffer_len, + false); + + /* Run the dispatcher with the keyboard. */ + view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen); + view_dispatcher_run(app->view_dispatcher); + + /* Undo all it: remove the view from the dispatcher, free it + * so that it removes itself from the current gui, finally + * restore our viewport. */ + view_dispatcher_remove_view(app->view_dispatcher, 0); + text_input_free(app->text_input); + view_dispatcher_free(app->view_dispatcher); + app->view_dispatcher = NULL; + gui_add_view_port(app->gui, app->view_port, GuiLayerFullscreen); + app->show_text_input = false; + } else { + view_port_update(app->view_port); + } } /* App no longer running. Shut down and free. */ diff --git a/applications/plugins/protoview/app.h b/applications/plugins/protoview/app.h index 52b0bff5b6..33bd85eb41 100644 --- a/applications/plugins/protoview/app.h +++ b/applications/plugins/protoview/app.h @@ -14,26 +14,36 @@ #include #include #include +#include #include #include #include #include #include #include -#include "app_buffer.h" +#include "raw_samples.h" #define TAG "ProtoView" -#define PROTOVIEW_RAW_VIEW_DEFAULT_SCALE 100 -#define BITMAP_SEEK_NOT_FOUND UINT32_MAX +#define PROTOVIEW_RAW_VIEW_DEFAULT_SCALE 100 // 100us is 1 pixel by default +#define BITMAP_SEEK_NOT_FOUND UINT32_MAX // Returned by function as sentinel +#define PROTOVIEW_VIEW_PRIVDATA_LEN 64 // View specific private data len #define DEBUG_MSG 1 +/* Forward declarations. */ + typedef struct ProtoViewApp ProtoViewApp; +typedef struct ProtoViewMsgInfo ProtoViewMsgInfo; +typedef struct ProtoViewFieldSet ProtoViewFieldSet; +typedef struct ProtoViewDecoder ProtoViewDecoder; + +/* ============================== enumerations ============================== */ /* Subghz system state */ typedef enum { TxRxStateIDLE, TxRxStateRx, + TxRxStateTx, TxRxStateSleep, } TxRxState; @@ -43,20 +53,24 @@ typedef enum { ViewInfo, ViewFrequencySettings, ViewModulationSettings, + ViewBuildMessage, ViewDirectSampling, ViewLast, /* Just a sentinel to wrap around. */ + + /* The following are special views that are not iterated, but + * have meaning for the API. */ + ViewGoNext, + ViewGoPrev, } ProtoViewCurrentView; -/* Used by app_switch_view() */ -typedef enum { - AppNextView, - AppPrevView -} SwitchViewDirection; +/* ================================== RX/TX ================================= */ typedef struct { - const char *name; - FuriHalSubGhzPreset preset; - uint8_t *custom; + const char *name; // Name to show to the user. + const char *id; // Identifier in the Flipper API/file. + FuriHalSubGhzPreset preset; // The preset ID. + uint8_t *custom; // If not null, a set of registers for + // the CC1101, specifying a custom preset. } ProtoViewModulation; extern ProtoViewModulation ProtoViewModulations[]; /* In app_subghz.c */ @@ -84,30 +98,35 @@ struct ProtoViewTxRx { typedef struct ProtoViewTxRx ProtoViewTxRx; -/* This stucture is filled by the decoder for specific protocols with the - * informations about the message. ProtoView will display such information - * in the message info view. */ -#define PROTOVIEW_MSG_STR_LEN 32 -typedef struct ProtoViewMsgInfo { - char name[PROTOVIEW_MSG_STR_LEN]; /* Protocol name and version. */ - char raw[PROTOVIEW_MSG_STR_LEN]; /* Protocol specific raw representation.*/ - /* The following is what the decoder wants to show to user. Each decoder - * can use the number of fileds it needs. */ - char info1[PROTOVIEW_MSG_STR_LEN]; /* Protocol specific info line 1. */ - char info2[PROTOVIEW_MSG_STR_LEN]; /* Protocol specific info line 2. */ - char info3[PROTOVIEW_MSG_STR_LEN]; /* Protocol specific info line 3. */ - char info4[PROTOVIEW_MSG_STR_LEN]; /* Protocol specific info line 4. */ - uint64_t len; /* Bits consumed from the stream. */ -} ProtoViewMsgInfo; +/* ============================== Main app state ============================ */ +#define ALERT_MAX_LEN 32 struct ProtoViewApp { /* GUI */ Gui *gui; + NotificationApp *notification; ViewPort *view_port; /* We just use a raw viewport and we render everything into the low level canvas. */ - ProtoViewCurrentView current_view; /* Active view ID. */ + ProtoViewCurrentView current_view; /* Active left-right view ID. */ + int current_subview[ViewLast]; /* Active up-down subview ID. */ FuriMessageQueue *event_queue; /* Keypress events go here. */ + /* Input text state. */ + ViewDispatcher *view_dispatcher; /* Used only when we want to show + the text_input view for a moment. + Otherwise it is set to null. */ + TextInput *text_input; + bool show_text_input; + char *text_input_buffer; + uint32_t text_input_buffer_len; + void (*text_input_done_callback)(void*); + + /* Alert state. */ + uint32_t alert_dismiss_time; /* Millisecond when the alert will be + no longer shown. Or zero if the alert + is currently not set at all. */ + char alert_text[ALERT_MAX_LEN]; /* Alert content. */ + /* Radio related. */ ProtoViewTxRx *txrx; /* Radio state. */ SubGhzSetting *setting; /* A list of valid frequencies. */ @@ -118,9 +137,16 @@ struct ProtoViewApp { uint32_t signal_last_scan_idx; /* Index of the buffer last time we performed the scan. */ bool signal_decoded; /* Was the current signal decoded? */ - ProtoViewMsgInfo signal_info; /* Decoded message, if signal_decoded true. */ + ProtoViewMsgInfo *msg_info; /* Decoded message info if not NULL. */ bool direct_sampling_enabled; /* This special view needs an explicit acknowledge to work. */ + void *view_privdata; /* This is a piece of memory of total size + PROTOVIEW_VIEW_PRIVDATA_LEN that it is + initialized to zero when we switch to + a a new view. While the view we are using + is the same, it can be used by the view to + store any kind of info inside, just casting + the pointer to a few specific-data structure. */ /* Raw view apps state. */ uint32_t us_scale; /* microseconds per pixel. */ @@ -132,6 +158,64 @@ struct ProtoViewApp { ProtoViewModulations table. */ }; +/* =========================== Protocols decoders =========================== */ + +/* This stucture is filled by the decoder for specific protocols with the + * informations about the message. ProtoView will display such information + * in the message info view. */ +#define PROTOVIEW_MSG_STR_LEN 32 +typedef struct ProtoViewMsgInfo { + ProtoViewDecoder *decoder; /* The decoder that decoded the message. */ + ProtoViewFieldSet *fieldset; /* Decoded fields. */ + /* Low level information of the detected signal: the following are filled + * by the protocol decoding function: */ + uint32_t start_off; /* Pulses start offset in the bitmap. */ + uint32_t pulses_count; /* Number of pulses of the full message. */ + /* The following are passed already filled to the decoder. */ + uint32_t short_pulse_dur; /* Microseconds duration of the short pulse. */ + /* The following are filled by ProtoView core after the decoder returned + * success. */ + uint8_t *bits; /* Bitmap with the signal. */ + uint32_t bits_bytes; /* Number of full bytes in the bitmap, that + is 'pulses_count/8' rounded to the next + integer. */ +} ProtoViewMsgInfo; + +/* This structures describe a set of protocol fields. It is used by decoders + * supporting message building to receive and return information about the + * protocol. */ +typedef enum { + FieldTypeStr, + FieldTypeSignedInt, + FieldTypeUnsignedInt, + FieldTypeBinary, + FieldTypeHex, + FieldTypeBytes, + FieldTypeFloat, +} ProtoViewFieldType; + +typedef struct { + ProtoViewFieldType type; + uint32_t len; // Depends on type: + // Bits for integers (signed,unsigned,binary,hex). + // Number of characters for strings. + // Number of nibbles for bytes (1 for each 4 bits). + // Number of digits after dot for floats. + char *name; // Field name. + union { + char *str; // String type. + int64_t value; // Signed integer type. + uint64_t uvalue; // Unsigned integer type. + uint8_t *bytes; // Raw bytes type. + float fvalue; // Float type. + }; +} ProtoViewField; + +typedef struct ProtoViewFieldSet { + ProtoViewField **fields; + uint32_t numfields; +} ProtoViewFieldSet; + typedef struct ProtoViewDecoder { const char *name; /* Protocol name. */ /* The decode function takes a buffer that is actually a bitmap, with @@ -142,6 +226,14 @@ typedef struct ProtoViewDecoder { * functions that perform bit extraction with bound checking, such as * bitmap_get() and so forth. */ bool (*decode)(uint8_t *bits, uint32_t numbytes, uint32_t numbits, ProtoViewMsgInfo *info); + /* This method is used by the decoder to return the fields it needs + * in order to build a new message. This way the message builder view + * can ask the user to fill the right set of fields of the specified + * type. */ + void (*get_fields)(ProtoViewFieldSet *fields); + /* This method takes the fields supported by the decoder, and + * renders a message in 'samples'. */ + void (*build_message)(RawSamplesBuffer *samples, ProtoViewFieldSet *fields); } ProtoViewDecoder; extern RawSamplesBuffer *RawSamples, *DetectedSamples; @@ -154,19 +246,26 @@ void radio_rx_end(ProtoViewApp* app); void radio_sleep(ProtoViewApp* app); void raw_sampling_worker_start(ProtoViewApp *app); void raw_sampling_worker_stop(ProtoViewApp *app); +void radio_tx_signal(ProtoViewApp *app, FuriHalSubGhzAsyncTxCallback data_feeder, void *ctx); /* signal.c */ uint32_t duration_delta(uint32_t a, uint32_t b); void reset_current_signal(ProtoViewApp *app); -void scan_for_signal(ProtoViewApp *app); +void scan_for_signal(ProtoViewApp *app,RawSamplesBuffer *source); bool bitmap_get(uint8_t *b, uint32_t blen, uint32_t bitpos); void bitmap_set(uint8_t *b, uint32_t blen, uint32_t bitpos, bool val); -void bitmap_set_pattern(uint8_t *b, uint32_t blen, const char *pat); -void bitmap_reverse_bytes(uint8_t *p, uint32_t len); +void bitmap_copy(uint8_t *d, uint32_t dlen, uint32_t doff, uint8_t *s, uint32_t slen, uint32_t soff, uint32_t count); +void bitmap_set_pattern(uint8_t *b, uint32_t blen, uint32_t off, const char *pat); +void bitmap_reverse_bytes_bits(uint8_t *p, uint32_t len); bool bitmap_match_bits(uint8_t *b, uint32_t blen, uint32_t bitpos, const char *bits); uint32_t bitmap_seek_bits(uint8_t *b, uint32_t blen, uint32_t startpos, uint32_t maxbits, const char *bits); uint32_t convert_from_line_code(uint8_t *buf, uint64_t buflen, uint8_t *bits, uint32_t len, uint32_t offset, const char *zero_pattern, const char *one_pattern); uint32_t convert_from_diff_manchester(uint8_t *buf, uint64_t buflen, uint8_t *bits, uint32_t len, uint32_t off, bool previous); +void init_msg_info(ProtoViewMsgInfo *i, ProtoViewApp *app); +void free_msg_info(ProtoViewMsgInfo *i); + +/* signal_file.c */ +bool save_signal(ProtoViewApp *app, const char *filename); /* view_*.c */ void render_view_raw_pulses(Canvas *const canvas, ProtoViewApp *app); @@ -177,12 +276,44 @@ void render_view_info(Canvas *const canvas, ProtoViewApp *app); void process_input_info(ProtoViewApp *app, InputEvent input); void render_view_direct_sampling(Canvas *const canvas, ProtoViewApp *app); void process_input_direct_sampling(ProtoViewApp *app, InputEvent input); +void render_view_build_message(Canvas *const canvas, ProtoViewApp *app); +void process_input_build_message(ProtoViewApp *app, InputEvent input); +void view_enter_build_message(ProtoViewApp *app); +void view_exit_build_message(ProtoViewApp *app); void view_enter_direct_sampling(ProtoViewApp *app); void view_exit_direct_sampling(ProtoViewApp *app); void view_exit_settings(ProtoViewApp *app); +void view_exit_info(ProtoViewApp *app); +void adjust_raw_view_scale(ProtoViewApp *app, uint32_t short_pulse_dur); /* ui.c */ +int ui_get_current_subview(ProtoViewApp *app); +void ui_show_available_subviews(Canvas *canvas, ProtoViewApp *app, int last_subview); +bool ui_process_subview_updown(ProtoViewApp *app, InputEvent input, int last_subview); +void ui_show_keyboard(ProtoViewApp *app, char *buffer, uint32_t buflen, + void (*done_callback)(void*)); +void ui_dismiss_keyboard(ProtoViewApp *app); +void ui_show_alert(ProtoViewApp *app, const char *text, uint32_t ttl); +void ui_dismiss_alert(ProtoViewApp *app); +void ui_draw_alert_if_needed(Canvas *canvas, ProtoViewApp *app); void canvas_draw_str_with_border(Canvas* canvas, uint8_t x, uint8_t y, const char* str, Color text_color, Color border_color); +/* fields.c */ +void fieldset_free(ProtoViewFieldSet *fs); +ProtoViewFieldSet *fieldset_new(void); +void fieldset_add_int(ProtoViewFieldSet *fs, const char *name, int64_t val, uint8_t bits); +void fieldset_add_uint(ProtoViewFieldSet *fs, const char *name, uint64_t uval, uint8_t bits); +void fieldset_add_hex(ProtoViewFieldSet *fs, const char *name, uint64_t uval, uint8_t bits); +void fieldset_add_bin(ProtoViewFieldSet *fs, const char *name, uint64_t uval, uint8_t bits); +void fieldset_add_str(ProtoViewFieldSet *fs, const char *name, const char *s); +void fieldset_add_bytes(ProtoViewFieldSet *fs, const char *name, const uint8_t *bytes, uint32_t count); +void fieldset_add_float(ProtoViewFieldSet *fs, const char *name, float val, uint32_t digits_after_dot); +const char *field_get_type_name(ProtoViewField *f); +int field_to_string(char *buf, size_t len, ProtoViewField *f); +bool field_set_from_string(ProtoViewField *f, char *buf, size_t len); +bool field_incr_value(ProtoViewField *f, int incr); +void fieldset_copy_matching_fields(ProtoViewFieldSet *dst, ProtoViewFieldSet *src); +void field_set_from_field(ProtoViewField *dst, ProtoViewField *src); + /* crc.c */ uint8_t crc8(const uint8_t *data, size_t len, uint8_t init, uint8_t poly); diff --git a/applications/plugins/protoview/app_subghz.c b/applications/plugins/protoview/app_subghz.c index ec7724b137..55905e8a32 100644 --- a/applications/plugins/protoview/app_subghz.c +++ b/applications/plugins/protoview/app_subghz.c @@ -13,17 +13,19 @@ void raw_sampling_worker_start(ProtoViewApp *app); void raw_sampling_worker_stop(ProtoViewApp *app); ProtoViewModulation ProtoViewModulations[] = { - {"OOK 650Khz", FuriHalSubGhzPresetOok650Async, NULL}, - {"OOK 270Khz", FuriHalSubGhzPresetOok270Async, NULL}, - {"2FSK 2.38Khz", FuriHalSubGhzPreset2FSKDev238Async, NULL}, - {"2FSK 47.6Khz", FuriHalSubGhzPreset2FSKDev476Async, NULL}, - {"MSK", FuriHalSubGhzPresetMSK99_97KbAsync, NULL}, - {"GFSK", FuriHalSubGhzPresetGFSK9_99KbAsync, NULL}, - {"TPMS 1 (FSK)", 0, (uint8_t*)protoview_subghz_tpms1_fsk_async_regs}, - {"TPMS 2 (OOK)", 0, (uint8_t*)protoview_subghz_tpms2_ook_async_regs}, - {"TPMS 3 (FSK)", 0, (uint8_t*)protoview_subghz_tpms3_fsk_async_regs}, - {"TPMS 4 (FSK)", 0, (uint8_t*)protoview_subghz_tpms4_fsk_async_regs}, - {NULL, 0, NULL} /* End of list sentinel. */ + {"OOK 650Khz", "FuriHalSubGhzPresetOok650Async", + FuriHalSubGhzPresetOok650Async, NULL}, + {"OOK 270Khz", "FuriHalSubGhzPresetOok270Async", + FuriHalSubGhzPresetOok270Async, NULL}, + {"2FSK 2.38Khz", "FuriHalSubGhzPreset2FSKDev238Async", + FuriHalSubGhzPreset2FSKDev238Async, NULL}, + {"2FSK 47.6Khz", "FuriHalSubGhzPreset2FSKDev476Async", + FuriHalSubGhzPreset2FSKDev476Async, NULL}, + {"TPMS 1 (FSK)", NULL, 0, (uint8_t*)protoview_subghz_tpms1_fsk_async_regs}, + {"TPMS 2 (OOK)", NULL, 0, (uint8_t*)protoview_subghz_tpms2_ook_async_regs}, + {"TPMS 3 (FSK)", NULL, 0, (uint8_t*)protoview_subghz_tpms3_fsk_async_regs}, + {"TPMS 4 (FSK)", NULL, 0, (uint8_t*)protoview_subghz_tpms4_fsk_async_regs}, + {NULL, NULL, 0, NULL} /* End of list sentinel. */ }; /* Called after the application initialization in order to setup the @@ -35,17 +37,26 @@ void radio_begin(ProtoViewApp* app) { furi_hal_subghz_reset(); furi_hal_subghz_idle(); + /* Power circuits are noisy. Suppressing the charge while we use + * ProtoView will improve the RF performances. */ + furi_hal_power_suppress_charge_enter(); + /* The CC1101 preset can be either one of the standard presets, if * the modulation "custom" field is NULL, or a custom preset we * defined in custom_presets.h. */ - if (ProtoViewModulations[app->modulation].custom == NULL) - furi_hal_subghz_load_preset(ProtoViewModulations[app->modulation].preset); - else - furi_hal_subghz_load_custom_preset(ProtoViewModulations[app->modulation].custom); + if (ProtoViewModulations[app->modulation].custom == NULL) { + furi_hal_subghz_load_preset( + ProtoViewModulations[app->modulation].preset); + } else { + furi_hal_subghz_load_custom_preset( + ProtoViewModulations[app->modulation].custom); + } furi_hal_gpio_init(&gpio_cc1101_g0, GpioModeInput, GpioPullNo, GpioSpeedLow); app->txrx->txrx_state = TxRxStateIDLE; } +/* ================================= Reception ============================== */ + /* Setup subghz to start receiving using a background worker. */ uint32_t radio_rx(ProtoViewApp* app) { furi_assert(app); @@ -76,6 +87,7 @@ uint32_t radio_rx(ProtoViewApp* app) { /* Stop subghz worker (if active), put radio on idle state. */ void radio_rx_end(ProtoViewApp* app) { furi_assert(app); + if (app->txrx->txrx_state == TxRxStateRx) { if (!app->txrx->debug_timer_sampling) { if(subghz_worker_is_running(app->txrx->worker)) { @@ -100,6 +112,33 @@ void radio_sleep(ProtoViewApp* app) { } furi_hal_subghz_sleep(); app->txrx->txrx_state = TxRxStateSleep; + furi_hal_power_suppress_charge_exit(); +} + +/* =============================== Transmission ============================= */ + +/* This function suspends the current RX state, switches to TX mode, + * transmits the signal provided by the callback data_feeder, and later + * restores the RX state if there was one. */ +void radio_tx_signal(ProtoViewApp *app, FuriHalSubGhzAsyncTxCallback data_feeder, void *ctx) { + TxRxState oldstate = app->txrx->txrx_state; + + if (oldstate == TxRxStateRx) radio_rx_end(app); + radio_begin(app); + + furi_hal_subghz_idle(); + uint32_t value = furi_hal_subghz_set_frequency_and_path(app->frequency); + FURI_LOG_E(TAG, "Switched to frequency: %lu", value); + furi_hal_gpio_write(&gpio_cc1101_g0, false); + furi_hal_gpio_init(&gpio_cc1101_g0, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); + + furi_hal_subghz_start_async_tx(data_feeder, ctx); + while(!furi_hal_subghz_is_async_tx_complete()) furi_delay_ms(10); + furi_hal_subghz_stop_async_tx(); + furi_hal_subghz_idle(); + + radio_begin(app); + if (oldstate == TxRxStateRx) radio_rx(app); } /* ============================= Raw sampling mode ============================= diff --git a/applications/plugins/protoview/binaries/README.md b/applications/plugins/protoview/binaries/README.md deleted file mode 100644 index 58113d7798..0000000000 --- a/applications/plugins/protoview/binaries/README.md +++ /dev/null @@ -1,10 +0,0 @@ -This is the binary distribution of the application. If you don't want -to build it from source, just take `protoview.fap` file and drop it into the -following Flipper Zero location: - - /ext/apps/Tools - -The `ext` part means that we are in the SD card. So if you don't want -to use the Android (or other) application to upload the file, -you can just take out the SD card, insert it in your computer, -copy the fine into `apps/Tools`, and that's it. diff --git a/applications/plugins/protoview/binaries/protoview.fap b/applications/plugins/protoview/binaries/protoview.fap deleted file mode 100644 index 696dc523ef..0000000000 Binary files a/applications/plugins/protoview/binaries/protoview.fap and /dev/null differ diff --git a/applications/plugins/protoview/binaries/update.sh b/applications/plugins/protoview/binaries/update.sh deleted file mode 100644 index 5a4ea0b4ea..0000000000 --- a/applications/plugins/protoview/binaries/update.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh -BINPATH="/Users/antirez/hack/flipper/official/build/f7-firmware-D/.extapps/protoview.fap" -cp $BINPATH . -git commit -a -m 'Binary file updated.' diff --git a/applications/plugins/protoview/custom_presets.h b/applications/plugins/protoview/custom_presets.h index 713827d228..cb9a421c6d 100644 --- a/applications/plugins/protoview/custom_presets.h +++ b/applications/plugins/protoview/custom_presets.h @@ -104,6 +104,9 @@ static uint8_t protoview_subghz_tpms1_fsk_async_regs[][2] = { /* End */ {0, 0}, + + /* CC1101 2FSK PATABLE. */ + {0xC0, 0}, {0,0}, {0,0}, {0,0} }; /* This is like the default Flipper OOK 640Khz bandwidth preset, but @@ -125,8 +128,8 @@ static const uint8_t protoview_subghz_tpms2_ook_async_regs[][2] = { {CC1101_MDMCFG0, 0x00}, // Channel spacing is 25kHz {CC1101_MDMCFG1, 0x00}, // Channel spacing is 25kHz {CC1101_MDMCFG2, 0x30}, // Format ASK/OOK, No preamble/sync - {CC1101_MDMCFG3, 0x93}, // Data rate is 10kBaud - {CC1101_MDMCFG4, 0x18}, // Rx BW filter is 650.000kHz + {CC1101_MDMCFG3, /*0x93*/ 0x32}, // Data rate is 10kBaud + {CC1101_MDMCFG4, /*0x18*/ 0x17}, // Rx BW filter is 650.000kHz /* Main Radio Control State Machine */ {CC1101_MCSM0, 0x18}, // Autocalibrate on idle-to-rx/tx, PO_TIMEOUT is 64 cycles(149-155us) @@ -151,6 +154,9 @@ static const uint8_t protoview_subghz_tpms2_ook_async_regs[][2] = { /* End */ {0, 0}, + + /* CC1101 OOK PATABLE. */ + {0, 0xC0}, {0,0}, {0,0}, {0,0} }; /* 40 KBaud, 2FSK, 28 kHz deviation, 270 Khz bandwidth filter. */ @@ -196,6 +202,9 @@ static uint8_t protoview_subghz_tpms3_fsk_async_regs[][2] = { /* End */ {0, 0}, + + /* CC1101 2FSK PATABLE. */ + {0xC0, 0}, {0,0}, {0,0}, {0,0} }; /* FSK 19k dev, 325 Khz filter, 20kBaud. Works well with Toyota. */ @@ -239,6 +248,8 @@ static uint8_t protoview_subghz_tpms4_fsk_async_regs[][2] = { /* End */ {0, 0}, -}; + /* CC1101 2FSK PATABLE. */ + {0xC0, 0}, {0,0}, {0,0}, {0,0} +}; diff --git a/applications/plugins/protoview/data_feed.c b/applications/plugins/protoview/data_feed.c index c3387fc4cd..a3bed238e0 100644 --- a/applications/plugins/protoview/data_feed.c +++ b/applications/plugins/protoview/data_feed.c @@ -6,7 +6,7 @@ #include #include #include -#include "app_buffer.h" +#include "raw_samples.h" #define TAG "PROTOVIEW-protocol" diff --git a/applications/plugins/protoview/fields.c b/applications/plugins/protoview/fields.c new file mode 100644 index 0000000000..bc62cda54b --- /dev/null +++ b/applications/plugins/protoview/fields.c @@ -0,0 +1,358 @@ +/* Copyright (C) 2022-2023 Salvatore Sanfilippo -- All Rights Reserved + * See the LICENSE file for information about the license. + * + * Protocol fields implementation. */ + +#include "app.h" + +/* Create a new field of the specified type. Without populating its + * type-specific value. */ +static ProtoViewField *field_new(ProtoViewFieldType type, const char *name) { + ProtoViewField *f = malloc(sizeof(*f)); + f->type = type; + f->name = strdup(name); + return f; +} + +/* Free only the auxiliary data of a field, used to represent the + * current type. Name and type are not touched. */ +static void field_free_aux_data(ProtoViewField *f) { + switch(f->type) { + case FieldTypeStr: free(f->str); break; + case FieldTypeBytes: free(f->bytes); break; + default: break; // Nothing to free for other types. + } +} + +/* Free a field an associated data. */ +static void field_free(ProtoViewField *f) { + field_free_aux_data(f); + free(f->name); + free(f); +} + +/* Return the type of the field as string. */ +const char *field_get_type_name(ProtoViewField *f) { + switch(f->type) { + case FieldTypeStr: return "str"; + case FieldTypeSignedInt: return "int"; + case FieldTypeUnsignedInt: return "uint"; + case FieldTypeBinary: return "bin"; + case FieldTypeHex: return "hex"; + case FieldTypeBytes: return "bytes"; + case FieldTypeFloat: return "float"; + } + return "unknown"; +} + +/* Set a string representation of the specified field in buf. */ +int field_to_string(char *buf, size_t len, ProtoViewField *f) { + switch(f->type) { + case FieldTypeStr: + return snprintf(buf,len,"%s", f->str); + case FieldTypeSignedInt: + return snprintf(buf,len,"%lld", (long long) f->value); + case FieldTypeUnsignedInt: + return snprintf(buf,len,"%llu", (unsigned long long) f->uvalue); + case FieldTypeBinary: + { + uint64_t test_bit = (1 << (f->len-1)); + uint64_t idx = 0; + while(idx < len-1 && test_bit) { + buf[idx++] = (f->uvalue & test_bit) ? '1' : '0'; + test_bit >>= 1; + } + buf[idx] = 0; + return idx; + } + case FieldTypeHex: + return snprintf(buf, len, "%*llX", (int)(f->len+7)/8, f->uvalue); + case FieldTypeFloat: + return snprintf(buf, len, "%.*f", (int)f->len, (double)f->fvalue); + case FieldTypeBytes: + { + uint64_t idx = 0; + while(idx < len-1 && idx < f->len) { + const char *charset = "0123456789ABCDEF"; + uint32_t nibble = idx & 1 ? + (f->bytes[idx/2] & 0xf) : + (f->bytes[idx/2] >> 4); + buf[idx++] = charset[nibble]; + } + buf[idx] = 0; + return idx; + } + } + return 0; +} + +/* Set the field value from its string representation in 'buf'. + * The field type must already be set and the field should be valid. + * The string represenation 'buf' must be null termianted. Note that + * even when representing binary values containing zero, this values + * are taken as representations, so that would be the string "00" as + * the Bytes type representation. + * + * The function returns true if the filed was successfully set to the + * new value, otherwise if the specified value is invalid for the + * field type, false is returned. */ +bool field_set_from_string(ProtoViewField *f, char *buf, size_t len) { + // Initialize values to zero since the Flipper sscanf() implementation + // is fuzzy... may populate only part of the value. + long long val = 0; + unsigned long long uval = 0; + float fval = 0; + + switch(f->type) { + case FieldTypeStr: + free(f->str); + f->len = len; + f->str = malloc(len+1); + memcpy(f->str,buf,len+1); + break; + case FieldTypeSignedInt: + if (!sscanf(buf,"%lld",&val)) return false; + f->value = val; + break; + case FieldTypeUnsignedInt: + if (!sscanf(buf,"%llu",&uval)) return false; + f->uvalue = uval; + break; + case FieldTypeBinary: + { + uint64_t bit_to_set = (1 << (len-1)); + uint64_t idx = 0; + uval = 0; + while(buf[idx]) { + if (buf[idx] == '1') uval |= bit_to_set; + else if (buf[idx] != '0') return false; + bit_to_set >>= 1; + idx++; + } + f->uvalue = uval; + } + break; + case FieldTypeHex: + if (!sscanf(buf,"%llx",&uval) && + !sscanf(buf,"%llX",&uval)) return false; + f->uvalue = uval; + break; + case FieldTypeFloat: + if (!sscanf(buf,"%f",&fval)) return false; + f->fvalue = fval; + break; + case FieldTypeBytes: + { + if (len > f->len) return false; + uint64_t idx = 0; + while(buf[idx]) { + uint8_t nibble = 0; + char c = toupper(buf[idx]); + if (c >= '0' && c <= '9') nibble = c-'0'; + else if (c >= 'A' && c <= 'F') nibble = 10+(c-'A'); + else return false; + + if (idx & 1) { + f->bytes[idx/2] = + (f->bytes[idx/2] & 0xF0) | nibble; + } else { + f->bytes[idx/2] = + (f->bytes[idx/2] & 0x0F) | (nibble<<4); + } + idx++; + } + buf[idx] = 0; + } + break; + } + return true; +} + +/* Set the 'dst' field to contain a copy of the value of the 'src' + * field. The field name is not modified. */ +void field_set_from_field(ProtoViewField *dst, ProtoViewField *src) { + field_free_aux_data(dst); + dst->type = src->type; + dst->len = src->len; + switch(src->type) { + case FieldTypeStr: + dst->str = strdup(src->str); + break; + case FieldTypeBytes: + dst->bytes = malloc(src->len); + memcpy(dst->bytes,src->bytes,dst->len); + break; + case FieldTypeSignedInt: + dst->value = src->value; + break; + case FieldTypeUnsignedInt: + case FieldTypeBinary: + case FieldTypeHex: + dst->uvalue = src->uvalue; + break; + case FieldTypeFloat: + dst->fvalue = src->fvalue; + break; + } +} + +/* Increment the specified field value of 'incr'. If the field type + * does not support increments false is returned, otherwise the + * action is performed. */ +bool field_incr_value(ProtoViewField *f, int incr) { + switch(f->type) { + case FieldTypeStr: return false; + case FieldTypeSignedInt: { + /* Wrap around depending on the number of bits (f->len) + * the integer was declared to have. */ + int64_t max = (1ULL << (f->len-1))-1; + int64_t min = -max-1; + int64_t v = (int64_t)f->value + incr; + if (v > max) v = min+(v-max-1); + if (v < min) v = max+(v-min+1); + f->value = v; + break; + } + case FieldTypeBinary: + case FieldTypeHex: + case FieldTypeUnsignedInt: { + /* Wrap around like for the unsigned case, but here + * is simpler. */ + uint64_t max = (1ULL << f->len)-1; // Broken for 64 bits. + uint64_t uv = (uint64_t)f->value + incr; + if (uv > max) uv = uv & max; + f->uvalue = uv; + break; + } + case FieldTypeFloat: + f->fvalue += incr; + break; + case FieldTypeBytes: { + // For bytes we only support single unit increments. + if (incr != -1 && incr != 1) return false; + for (int j = f->len-1; j >= 0; j--) { + uint8_t nibble = (j&1) ? (f->bytes[j/2] & 0x0F) : + ((f->bytes[j/2] & 0xF0) >> 4); + + nibble += incr; + nibble &= 0x0F; + + f->bytes[j/2] = (j&1) ? ((f->bytes[j/2] & 0xF0) | nibble) : + ((f->bytes[j/2] & 0x0F) | (nibble<<4)); + + /* Propagate the operation on overflow of this nibble. */ + if ((incr == 1 && nibble == 0) || + (incr == -1 && nibble == 0xf)) + { + continue; + } + break; // Otherwise stop the loop here. + } + break; + } + } + return true; +} + + +/* Free a field set and its contained fields. */ +void fieldset_free(ProtoViewFieldSet *fs) { + for (uint32_t j = 0; j < fs->numfields; j++) + field_free(fs->fields[j]); + free(fs->fields); + free(fs); +} + +/* Allocate and init an empty field set. */ +ProtoViewFieldSet *fieldset_new(void) { + ProtoViewFieldSet *fs = malloc(sizeof(*fs)); + fs->numfields = 0; + fs->fields = NULL; + return fs; +} + +/* Append an already allocated field at the end of the specified field set. */ +static void fieldset_add_field(ProtoViewFieldSet *fs, ProtoViewField *field) { + fs->numfields++; + fs->fields = realloc(fs->fields,sizeof(ProtoViewField*)*fs->numfields); + fs->fields[fs->numfields-1] = field; +} + +/* Allocate and append an integer field. */ +void fieldset_add_int(ProtoViewFieldSet *fs, const char *name, int64_t val, uint8_t bits) { + ProtoViewField *f = field_new(FieldTypeSignedInt,name); + f->value = val; + f->len = bits; + fieldset_add_field(fs,f); +} + +/* Allocate and append an unsigned field. */ +void fieldset_add_uint(ProtoViewFieldSet *fs, const char *name, uint64_t uval, uint8_t bits) { + ProtoViewField *f = field_new(FieldTypeUnsignedInt,name); + f->uvalue = uval; + f->len = bits; + fieldset_add_field(fs,f); +} + +/* Allocate and append a hex field. This is an unsigned number but + * with an hex representation. */ +void fieldset_add_hex(ProtoViewFieldSet *fs, const char *name, uint64_t uval, uint8_t bits) { + ProtoViewField *f = field_new(FieldTypeHex,name); + f->uvalue = uval; + f->len = bits; + fieldset_add_field(fs,f); +} + +/* Allocate and append a bin field. This is an unsigned number but + * with a binary representation. */ +void fieldset_add_bin(ProtoViewFieldSet *fs, const char *name, uint64_t uval, uint8_t bits) { + ProtoViewField *f = field_new(FieldTypeBinary,name); + f->uvalue = uval; + f->len = bits; + fieldset_add_field(fs,f); +} + +/* Allocate and append a string field. */ +void fieldset_add_str(ProtoViewFieldSet *fs, const char *name, const char *s) { + ProtoViewField *f = field_new(FieldTypeStr,name); + f->str = strdup(s); + f->len = strlen(s); + fieldset_add_field(fs,f); +} + +/* Allocate and append a bytes field. Note that 'count' is specified in + * nibbles (bytes*2). */ +void fieldset_add_bytes(ProtoViewFieldSet *fs, const char *name, const uint8_t *bytes, uint32_t count_nibbles) { + uint32_t numbytes = (count_nibbles+count_nibbles%2)/2; + ProtoViewField *f = field_new(FieldTypeBytes,name); + f->bytes = malloc(numbytes); + memcpy(f->bytes,bytes,numbytes); + f->len = count_nibbles; + fieldset_add_field(fs,f); +} + +/* Allocate and append a float field. */ +void fieldset_add_float(ProtoViewFieldSet *fs, const char *name, float val, uint32_t digits_after_dot) { + ProtoViewField *f = field_new(FieldTypeFloat,name); + f->fvalue = val; + f->len = digits_after_dot; + fieldset_add_field(fs,f); +} + +/* For each field of the destination filedset 'dst', look for a matching + * field name/type in the source fieldset 'src', and if one is found copy + * its value into the 'dst' field. */ +void fieldset_copy_matching_fields(ProtoViewFieldSet *dst, + ProtoViewFieldSet *src) +{ + for (uint32_t j = 0; j < dst->numfields; j++) { + for (uint32_t i = 0; i < src->numfields; i++) { + if (dst->fields[j]->type == src->fields[i]->type && + !strcmp(dst->fields[j]->name,src->fields[i]->name)) + { + field_set_from_field(dst->fields[j], + src->fields[i]); + } + } + } +} diff --git a/applications/plugins/protoview/protocols/b4b1.c b/applications/plugins/protoview/protocols/b4b1.c index 2bed2ac32f..7308d1211b 100644 --- a/applications/plugins/protoview/protocols/b4b1.c +++ b/applications/plugins/protoview/protocols/b4b1.c @@ -25,6 +25,9 @@ static bool decode(uint8_t *bits, uint32_t numbytes, uint32_t numbits, ProtoView } if (off == BITMAP_SEEK_NOT_FOUND) return false; if (DEBUG_MSG) FURI_LOG_E(TAG, "B4B1 preamble at: %lu",off); + info->start_off = off; + + // Seek data setction. Why -1? Last bit is data. off += strlen(sync_patterns[j])-1; uint8_t d[3]; /* 24 bits of data. */ @@ -32,13 +35,54 @@ static bool decode(uint8_t *bits, uint32_t numbytes, uint32_t numbits, ProtoView convert_from_line_code(d,sizeof(d),bits,numbytes,off,"1000","1110"); if (DEBUG_MSG) FURI_LOG_E(TAG, "B4B1 decoded: %lu",decoded); - if (decoded != 24) return false; - snprintf(info->name,PROTOVIEW_MSG_STR_LEN,"PT/SC remote"); - snprintf(info->raw,PROTOVIEW_MSG_STR_LEN,"%02X%02X%02X",d[0],d[1],d[2]); - info->len = off+(4*24); + if (decoded < 24) return false; + + off += 24*4; // seek to end symbol offset to calculate the length. + off++; // In this protocol there is a final pulse as terminator. + info->pulses_count = off - info->start_off; + + fieldset_add_bytes(info->fieldset,"id",d,5); + fieldset_add_uint(info->fieldset,"button",d[2]&0xf,4); return true; } +/* Give fields and defaults for the signal creator. */ +static void get_fields(ProtoViewFieldSet *fieldset) { + uint8_t default_id[3]= {0xAB, 0xCD, 0xE0}; + fieldset_add_bytes(fieldset,"id",default_id,5); + fieldset_add_uint(fieldset,"button",1,4); +} + +/* Create a signal. */ +static void build_message(RawSamplesBuffer *samples, ProtoViewFieldSet *fs) +{ + uint32_t te = 334; // Short pulse duration in microseconds. + + // Sync: 1 te pulse, 31 te gap. + raw_samples_add(samples,true,te); + raw_samples_add(samples,false,te*31); + + // ID + button state + uint8_t data[3]; + memcpy(data,fs->fields[0]->bytes,3); + data[2] = (data[2]&0xF0) | (fs->fields[1]->uvalue & 0xF); + for (uint32_t j = 0; j < 24; j++) { + if (bitmap_get(data,sizeof(data),j)) { + raw_samples_add(samples,true,te*3); + raw_samples_add(samples,false,te); + } else { + raw_samples_add(samples,true,te); + raw_samples_add(samples,false,te*3); + } + } + + // Signal terminator. Just a single short pulse. + raw_samples_add(samples,true,te); +} + ProtoViewDecoder B4B1Decoder = { - "B4B1", decode + .name = "PT/SC remote", + .decode = decode, + .get_fields = get_fields, + .build_message = build_message }; diff --git a/applications/plugins/protoview/protocols/keeloq.c b/applications/plugins/protoview/protocols/keeloq.c index cf0b7682f5..0741eac477 100644 --- a/applications/plugins/protoview/protocols/keeloq.c +++ b/applications/plugins/protoview/protocols/keeloq.c @@ -32,9 +32,11 @@ static bool decode(uint8_t *bits, uint32_t numbytes, uint32_t numbits, ProtoView const char *sync_pattern = "101010101010101010101010" "0000"; uint8_t sync_len = 24+4; if (numbits-sync_len+sync_len < 3*66) return false; - uint64_t off = bitmap_seek_bits(bits,numbytes,0,numbits,sync_pattern); + uint32_t off = bitmap_seek_bits(bits,numbytes,0,numbits,sync_pattern); if (off == BITMAP_SEEK_NOT_FOUND) return false; - off += sync_len; + + info->start_off = off; + off += sync_len; // Seek start of message. /* Now there is half the gap left, but we allow from 3 to 7, instead of 5 * symbols of gap, to avoid missing the signal for a matter of wrong @@ -52,36 +54,72 @@ static bool decode(uint8_t *bits, uint32_t numbytes, uint32_t numbits, ProtoView convert_from_line_code(raw,sizeof(raw),bits,numbytes,off, "110","100"); /* Pulse width modulation. */ FURI_LOG_E(TAG, "Keeloq decoded bits: %lu", decoded); - if (decoded < 66) return false; /* Require the full 66 bits. */ - bitmap_reverse_bytes(raw,sizeof(raw)); /* Keeloq is LSB first. */ + + info->pulses_count = (off+66*3) - info->start_off; + + bitmap_reverse_bytes_bits(raw,sizeof(raw)); /* Keeloq is LSB first. */ int buttons = raw[7]>>4; - int s3 = (buttons&1) != 0; - int s0 = (buttons&2) != 0; - int s1 = (buttons&4) != 0; - int s2 = (buttons&8) != 0; - - int remote_id = ((raw[7]&0x0f) << 24) | - (raw[6] << 16) | - (raw[5] << 8) | - (raw[4] << 0); - int lowbat = raw[8]&0x80; - - snprintf(info->name,sizeof(info->name),"%s","Keeloq remote"); - snprintf(info->raw,sizeof(info->raw),"%02X%02X%02X%02X%02X%02X%02X%02X%02X", - raw[0],raw[1],raw[2],raw[3],raw[4],raw[5], - raw[6],raw[7],raw[8]); - snprintf(info->info1,sizeof(info->info1),"Encrpyted %02X%02X%02X%02X", - raw[3],raw[2],raw[1],raw[0]); - snprintf(info->info2,sizeof(info->info2),"ID %08X", remote_id); - snprintf(info->info3,sizeof(info->info3),"s0-s3: %d%d%d%d", - s0,s1,s2,s3); - snprintf(info->info4,sizeof(info->info4),"Low battery? %s", - lowbat ? "yes" : "no"); + int lowbat = (raw[8]&0x1) == 0; // Actual bit meaning: good battery level + int alwaysone = (raw[8]&0x2) != 0; + + fieldset_add_bytes(info->fieldset,"encr",raw,8); + raw[7] = raw[7]<<4; // Make ID bits contiguous + fieldset_add_bytes(info->fieldset,"id",raw+4,7); // 28 bits, 7 nibbles + fieldset_add_bin(info->fieldset,"s[2,1,0,3]",buttons,4); + fieldset_add_bin(info->fieldset,"low battery",lowbat,1); + fieldset_add_bin(info->fieldset,"always one",alwaysone,1); return true; } +static void get_fields(ProtoViewFieldSet *fieldset) { + uint8_t remote_id[4] = {0xab, 0xcd, 0xef, 0xa0}; + uint8_t encr[4] = {0xab, 0xab, 0xab, 0xab}; + fieldset_add_bytes(fieldset,"encr",encr,8); + fieldset_add_bytes(fieldset,"id",remote_id,7); + fieldset_add_bin(fieldset,"s[2,1,0,3]",2,4); + fieldset_add_bin(fieldset,"low battery",0,1); + fieldset_add_bin(fieldset,"always one",1,1); +} + +static void build_message(RawSamplesBuffer *samples, ProtoViewFieldSet *fieldset) +{ + uint32_t te = 380; // Short pulse duration in microseconds. + + // Sync: 12 pairs of pulse/gap + 9 times gap + for (int j = 0; j < 12; j++) { + raw_samples_add(samples,true,te); + raw_samples_add(samples,false,te); + } + raw_samples_add(samples,false,te*9); + + // Data, 66 bits. + uint8_t data[9] = {0}; + memcpy(data,fieldset->fields[0]->bytes,4); // Encrypted part. + memcpy(data+4,fieldset->fields[1]->bytes,4); // ID. + data[7] = data[7]>>4 | fieldset->fields[2]->uvalue << 4; // s[2,1,0,3] + int low_battery = fieldset->fields[3] != 0; + int always_one = fieldset->fields[4] != 0; + low_battery = !low_battery; // Bit real meaning is good battery level. + data[8] |= low_battery; + data[8] |= (always_one << 1); + bitmap_reverse_bytes_bits(data,sizeof(data)); /* Keeloq is LSB first. */ + + for (int j = 0; j < 66; j++) { + if (bitmap_get(data,9,j)) { + raw_samples_add(samples,true,te); + raw_samples_add(samples,false,te*2); + } else { + raw_samples_add(samples,true,te*2); + raw_samples_add(samples,false,te); + } + } +} + ProtoViewDecoder KeeloqDecoder = { - "Keeloq", decode + .name = "Keeloq", + .decode = decode, + .get_fields = get_fields, + .build_message = build_message }; diff --git a/applications/plugins/protoview/protocols/oregon2.c b/applications/plugins/protoview/protocols/oregon2.c index 3aa57c72d0..1d909a5040 100644 --- a/applications/plugins/protoview/protocols/oregon2.c +++ b/applications/plugins/protoview/protocols/oregon2.c @@ -13,6 +13,7 @@ static bool decode(uint8_t *bits, uint32_t numbytes, uint32_t numbits, ProtoView if (off == BITMAP_SEEK_NOT_FOUND) return false; FURI_LOG_E(TAG, "Oregon2 preamble+sync found"); + info->start_off = off; off += 32; /* Skip preamble. */ uint8_t buffer[8], raw[8] = {0}; @@ -21,8 +22,10 @@ static bool decode(uint8_t *bits, uint32_t numbytes, uint32_t numbits, ProtoView FURI_LOG_E(TAG, "Oregon2 decoded bits: %lu", decoded); if (decoded < 11*4) return false; /* Minimum len to extract some data. */ + info->pulses_count = (off+11*4*4) - info->start_off; - char temp[3] = {0}, deviceid[2] = {0}, hum[2] = {0}; + char temp[3] = {0}, hum[2] = {0}; + uint8_t deviceid[2]; for (int j = 0; j < 64; j += 4) { uint8_t nib[1]; nib[0] = (bitmap_get(buffer,8,j+0) | @@ -45,21 +48,20 @@ static bool decode(uint8_t *bits, uint32_t numbytes, uint32_t numbits, ProtoView } } - snprintf(info->name,sizeof(info->name),"%s","Oregon v2.1"); - /* The following line crashes the Flipper because of broken - * snprintf() implementation. */ - snprintf(info->raw,sizeof(info->raw),"%02X%02X%02X%02X%02X%02X%02X%02X", - raw[0],raw[1],raw[2],raw[3],raw[4],raw[5], - raw[6],raw[7]); - snprintf(info->info1,sizeof(info->info1),"Sensor ID %02X%02X", - deviceid[0], deviceid[1]); - snprintf(info->info2,sizeof(info->info2),"Temperature %d%d.%d", - temp[0],temp[1],temp[2]); - snprintf(info->info3,sizeof(info->info3),"Humidity %d%d", - hum[0],hum[1]); + float tempval = ((temp[0]-'0')*10) + + (temp[1]-'0') + + ((float)(temp[2]-'0')*0.1); + int humval = (hum[0]-'0')*10 + (hum[1]-'0'); + + fieldset_add_bytes(info->fieldset,"Sensor ID",deviceid,4); + fieldset_add_float(info->fieldset,"Temperature",tempval,1); + fieldset_add_uint(info->fieldset,"Humidity",humval,7); return true; } ProtoViewDecoder Oregon2Decoder = { - "Oregon2", decode + .name = "Oregon2", + .decode = decode, + .get_fields = NULL, + .build_message = NULL }; diff --git a/applications/plugins/protoview/protocols/tpms/citroen.c b/applications/plugins/protoview/protocols/tpms/citroen.c index 809dc0a252..d8a1681e49 100644 --- a/applications/plugins/protoview/protocols/tpms/citroen.c +++ b/applications/plugins/protoview/protocols/tpms/citroen.c @@ -20,6 +20,7 @@ static bool decode(uint8_t *bits, uint32_t numbytes, uint32_t numbits, ProtoView if (off == BITMAP_SEEK_NOT_FOUND) return false; FURI_LOG_E(TAG, "Renault TPMS preamble+sync found"); + info->start_off = off; off += sync_len; /* Skip preamble + sync. */ uint8_t raw[10]; @@ -37,24 +38,24 @@ static bool decode(uint8_t *bits, uint32_t numbytes, uint32_t numbits, ProtoView for (int j = 1; j < 10; j++) crc ^= raw[j]; if (crc != 0) return false; /* Require sane checksum. */ + info->pulses_count = (off+8*10*2) - info->start_off; + int repeat = raw[5] & 0xf; float kpa = (float)raw[6]*1.364; int temp = raw[7]-50; int battery = raw[8]; /* This may be the battery. It's not clear. */ - snprintf(info->name,sizeof(info->name),"%s","Citroen TPMS"); - snprintf(info->raw,sizeof(info->raw), - "%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X", - raw[0],raw[1],raw[2],raw[3],raw[4],raw[5], - raw[6],raw[7],raw[8],raw[9]); - snprintf(info->info1,sizeof(info->info1),"Tire ID %02X%02X%02X%02X", - raw[1],raw[2],raw[3],raw[4]); - snprintf(info->info2,sizeof(info->info2),"Pressure %.2f kpa", (double)kpa); - snprintf(info->info3,sizeof(info->info3),"Temperature %d C", temp); - snprintf(info->info4,sizeof(info->info4),"Repeat %d, Bat %d", repeat, battery); + fieldset_add_bytes(info->fieldset,"Tire ID",raw+1,4*2); + fieldset_add_float(info->fieldset,"Pressure kpa",kpa,2); + fieldset_add_int(info->fieldset,"Temperature C",temp,8); + fieldset_add_uint(info->fieldset,"Repeat",repeat,4); + fieldset_add_uint(info->fieldset,"Battery",battery,8); return true; } ProtoViewDecoder CitroenTPMSDecoder = { - "Citroen TPMS", decode + .name = "Citroen TPMS", + .decode = decode, + .get_fields = NULL, + .build_message = NULL }; diff --git a/applications/plugins/protoview/protocols/tpms/ford.c b/applications/plugins/protoview/protocols/tpms/ford.c index a9c687075d..abdb692ee5 100644 --- a/applications/plugins/protoview/protocols/tpms/ford.c +++ b/applications/plugins/protoview/protocols/tpms/ford.c @@ -20,6 +20,7 @@ static bool decode(uint8_t *bits, uint32_t numbytes, uint32_t numbits, ProtoView if (off == BITMAP_SEEK_NOT_FOUND) return false; FURI_LOG_E(TAG, "Fort TPMS preamble+sync found"); + info->start_off = off; off += sync_len; /* Skip preamble and sync. */ uint8_t raw[8]; @@ -35,6 +36,8 @@ static bool decode(uint8_t *bits, uint32_t numbytes, uint32_t numbits, ProtoView for (int j = 0; j < 7; j++) crc += raw[j]; if (crc != raw[7]) return false; /* Require sane CRC. */ + info->pulses_count = (off+8*8*2) - info->start_off; + float psi = 0.25 * (((raw[6]&0x20)<<3)|raw[4]); /* Temperature apperas to be valid only if the most significant @@ -44,21 +47,17 @@ static bool decode(uint8_t *bits, uint32_t numbytes, uint32_t numbits, ProtoView int flags = raw[5] & 0x7f; int car_moving = (raw[6] & 0x44) == 0x44; - snprintf(info->name,sizeof(info->name),"%s","Ford TPMS"); - snprintf(info->raw,sizeof(info->raw),"%02X%02X%02X%02X%02X%02X%02X%02X", - raw[0],raw[1],raw[2],raw[3],raw[4],raw[5], - raw[6],raw[7]); - snprintf(info->info1,sizeof(info->info1),"Tire ID %02X%02X%02X%02X", - raw[0],raw[1],raw[2],raw[3]); - snprintf(info->info2,sizeof(info->info2),"Pressure %.2f psi", (double)psi); - if (temp) - snprintf(info->info3,sizeof(info->info3),"Temperature %d C", temp); - else - snprintf(info->info3,sizeof(info->info3),"Flags %d", flags); - snprintf(info->info4,sizeof(info->info4),"Moving %s", car_moving ? "yes" : "no"); + fieldset_add_bytes(info->fieldset,"Tire ID",raw,4*2); + fieldset_add_float(info->fieldset,"Pressure psi",psi,2); + fieldset_add_int(info->fieldset,"Temperature C",temp,8); + fieldset_add_hex(info->fieldset,"Flags",flags,7); + fieldset_add_uint(info->fieldset,"Moving",car_moving,1); return true; } ProtoViewDecoder FordTPMSDecoder = { - "Ford TPMS", decode + .name = "Ford TPMS", + .decode = decode, + .get_fields = NULL, + .build_message = NULL }; diff --git a/applications/plugins/protoview/protocols/tpms/renault.c b/applications/plugins/protoview/protocols/tpms/renault.c index 4bbe55e42a..09de77d17b 100644 --- a/applications/plugins/protoview/protocols/tpms/renault.c +++ b/applications/plugins/protoview/protocols/tpms/renault.c @@ -25,7 +25,7 @@ static const char *test_vector = static bool decode(uint8_t *bits, uint32_t numbytes, uint32_t numbits, ProtoViewMsgInfo *info) { if (USE_TEST_VECTOR) { /* Test vector to check that decoding works. */ - bitmap_set_pattern(bits,numbytes,test_vector); + bitmap_set_pattern(bits,numbytes,0,test_vector); numbits = strlen(test_vector); } @@ -36,6 +36,7 @@ static bool decode(uint8_t *bits, uint32_t numbytes, uint32_t numbits, ProtoView if (off == BITMAP_SEEK_NOT_FOUND) return false; FURI_LOG_E(TAG, "Renault TPMS preamble+sync found"); + info->start_off = off; off += 20; /* Skip preamble. */ uint8_t raw[9]; @@ -47,20 +48,73 @@ static bool decode(uint8_t *bits, uint32_t numbytes, uint32_t numbits, ProtoView if (decoded < 8*9) return false; /* Require the full 9 bytes. */ if (crc8(raw,8,0,7) != raw[8]) return false; /* Require sane CRC. */ - float kpa = 0.75 *((uint32_t)((raw[0]&3)<<8) | raw[1]); + info->pulses_count = (off+8*9*2) - info->start_off; + + uint8_t flags = raw[0]>>2; + float kpa = 0.75 * ((uint32_t)((raw[0]&3)<<8) | raw[1]); int temp = raw[2]-30; - snprintf(info->name,sizeof(info->name),"%s","Renault TPMS"); - snprintf(info->raw,sizeof(info->raw),"%02X%02X%02X%02X%02X%02X%02X%02X%02X", - raw[0],raw[1],raw[2],raw[3],raw[4],raw[5], - raw[6],raw[7],raw[8]); - snprintf(info->info1,sizeof(info->info1),"Tire ID %02X%02X%02X", - raw[3],raw[4],raw[5]); - snprintf(info->info2,sizeof(info->info2),"Pressure %.2f kpa", (double)kpa); - snprintf(info->info3,sizeof(info->info3),"Temperature %d C", temp); + fieldset_add_bytes(info->fieldset,"Tire ID",raw+3,3*2); + fieldset_add_float(info->fieldset,"Pressure kpa",kpa,2); + fieldset_add_int(info->fieldset,"Temperature C",temp,8); + fieldset_add_hex(info->fieldset,"Flags",flags,6); + fieldset_add_bytes(info->fieldset,"Unknown1",raw+6,2); + fieldset_add_bytes(info->fieldset,"Unknown2",raw+7,2); return true; } +/* Give fields and defaults for the signal creator. */ +static void get_fields(ProtoViewFieldSet *fieldset) { + uint8_t default_id[3]= {0xAB, 0xCD, 0xEF}; + fieldset_add_bytes(fieldset,"Tire ID",default_id,3*2); + fieldset_add_float(fieldset,"Pressure kpa",123,2); + fieldset_add_int(fieldset,"Temperature C",20,8); + // We don't know what flags are, but 1B is a common value. + fieldset_add_hex(fieldset,"Flags",0x1b,6); + fieldset_add_bytes(fieldset,"Unknown1",(uint8_t*)"\xff",2); + fieldset_add_bytes(fieldset,"Unknown2",(uint8_t*)"\xff",2); +} + +/* Create a Renault TPMS signal, according to the fields provided. */ +static void build_message(RawSamplesBuffer *samples, ProtoViewFieldSet *fieldset) +{ + uint32_t te = 50; // Short pulse duration in microseconds. + + // Preamble + sync + const char *psync = "01010101010101010101010101010110"; + const char *p = psync; + while(*p) { + raw_samples_add_or_update(samples,*p == '1',te); + p++; + } + + // Data, 9 bytes + uint8_t data[9] = {0}; + unsigned int raw_pressure = fieldset->fields[1]->fvalue * 4 / 3; + data[0] = fieldset->fields[3]->uvalue << 2; // Flags + data[0] |= (raw_pressure >> 8) & 3; // Pressure kpa high 2 bits + data[1] = raw_pressure & 0xff; // Pressure kpa low 8 bits + data[2] = fieldset->fields[2]->value + 30; // Temperature C + memcpy(data+3,fieldset->fields[0]->bytes,6); // ID, 24 bits. + data[6] = fieldset->fields[4]->bytes[0]; // Unknown 1 + data[7] = fieldset->fields[5]->bytes[0]; // Unknown 2 + data[8] = crc8(data,8,0,7); + + // Generate Manchester code for each bit + for (uint32_t j = 0; j < 9*8; j++) { + if (bitmap_get(data,sizeof(data),j)) { + raw_samples_add_or_update(samples,true,te); + raw_samples_add_or_update(samples,false,te); + } else { + raw_samples_add_or_update(samples,false,te); + raw_samples_add_or_update(samples,true,te); + } + } +} + ProtoViewDecoder RenaultTPMSDecoder = { - "Renault TPMS", decode + .name = "Renault TPMS", + .decode = decode, + .get_fields = get_fields, + .build_message = build_message }; diff --git a/applications/plugins/protoview/protocols/tpms/schrader.c b/applications/plugins/protoview/protocols/tpms/schrader.c index ab65a92d39..ae25e39bb8 100644 --- a/applications/plugins/protoview/protocols/tpms/schrader.c +++ b/applications/plugins/protoview/protocols/tpms/schrader.c @@ -16,7 +16,7 @@ static const char *test_vector = "0000001111010101010110100101100101101010010101 static bool decode(uint8_t *bits, uint32_t numbytes, uint32_t numbits, ProtoViewMsgInfo *info) { if (USE_TEST_VECTOR) { /* Test vector to check that decoding works. */ - bitmap_set_pattern(bits,numbytes,test_vector); + bitmap_set_pattern(bits,numbytes,0,test_vector); numbits = strlen(test_vector); } @@ -27,11 +27,13 @@ static bool decode(uint8_t *bits, uint32_t numbytes, uint32_t numbits, ProtoView if (off == BITMAP_SEEK_NOT_FOUND) return false; FURI_LOG_E(TAG, "Schrader TPMS gap+preamble found"); + info->start_off = off; off += 10; /* Skip just the long pulse and the first 3 bits of sync, so that we have the first byte of data with the sync nibble 0011 = 0x3. */ uint8_t raw[8]; + uint8_t id[4]; uint32_t decoded = convert_from_line_code(raw,sizeof(raw),bits,numbytes,off, "01","10"); /* Manchester code. */ @@ -46,20 +48,24 @@ static bool decode(uint8_t *bits, uint32_t numbytes, uint32_t numbits, ProtoView return false; } + info->pulses_count = (off+8*8*2) - info->start_off; + float kpa = (float)raw[5]*2.5; int temp = raw[6]-50; + id[0] = raw[1]&7; + id[1] = raw[2]; + id[2] = raw[3]; + id[3] = raw[4]; - snprintf(info->name,sizeof(info->name),"%s","Schrader TPMS"); - snprintf(info->raw,sizeof(info->raw),"%02X%02X%02X%02X%02X%02X%02X%02X", - raw[0],raw[1],raw[2],raw[3],raw[4],raw[5], - raw[6],raw[7]); - snprintf(info->info1,sizeof(info->info1),"Tire ID %01X%02X%02X%02X", - raw[1]&7,raw[2],raw[3],raw[4]); /* Only 28 bits of ID, not 32. */ - snprintf(info->info2,sizeof(info->info2),"Pressure %.2f kpa", (double)kpa); - snprintf(info->info3,sizeof(info->info3),"Temperature %d C", temp); + fieldset_add_bytes(info->fieldset,"Tire ID",id,4*2); + fieldset_add_float(info->fieldset,"Pressure kpa",kpa,2); + fieldset_add_int(info->fieldset,"Temperature C",temp,8); return true; } ProtoViewDecoder SchraderTPMSDecoder = { - "Schrader TPMS", decode + .name = "Schrader TPMS", + .decode = decode, + .get_fields = NULL, + .build_message = NULL }; diff --git a/applications/plugins/protoview/protocols/tpms/schrader_eg53ma4.c b/applications/plugins/protoview/protocols/tpms/schrader_eg53ma4.c index 6fce40d64e..0105010bdd 100644 --- a/applications/plugins/protoview/protocols/tpms/schrader_eg53ma4.c +++ b/applications/plugins/protoview/protocols/tpms/schrader_eg53ma4.c @@ -25,6 +25,7 @@ static bool decode(uint8_t *bits, uint32_t numbytes, uint32_t numbits, ProtoView if (off == BITMAP_SEEK_NOT_FOUND) return false; FURI_LOG_E(TAG, "Schrader EG53MA4 TPMS preamble+sync found"); + info->start_off = off; off += sync_len-8; /* Skip preamble, not sync that is part of the data. */ uint8_t raw[10]; @@ -40,6 +41,8 @@ static bool decode(uint8_t *bits, uint32_t numbytes, uint32_t numbits, ProtoView for (int j = 0; j < 9; j++) crc += raw[j]; if (crc != raw[9]) return false; /* Require sane CRC. */ + info->pulses_count = (off+10*8*2) - info->start_off; + /* To convert the raw pressure to kPa, RTL433 uses 2.5, but is likely * wrong. Searching on Google for users experimenting with the value * reported, the value appears to be 2.75. */ @@ -47,17 +50,15 @@ static bool decode(uint8_t *bits, uint32_t numbytes, uint32_t numbits, ProtoView int temp_f = raw[8]; int temp_c = (temp_f-32)*5/9; /* Convert Fahrenheit to Celsius. */ - snprintf(info->name,sizeof(info->name),"%s","Schrader EG53MA4 TPMS"); - snprintf(info->raw,sizeof(info->raw),"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X", - raw[0],raw[1],raw[2],raw[3],raw[4],raw[5], - raw[6],raw[7],raw[8],raw[9]); - snprintf(info->info1,sizeof(info->info1),"Tire ID %02X%02X%02X", - raw[4],raw[5],raw[6]); /* Only 28 bits of ID, not 32. */ - snprintf(info->info2,sizeof(info->info2),"Pressure %.2f kpa", (double)kpa); - snprintf(info->info3,sizeof(info->info3),"Temperature %d C", temp_c); + fieldset_add_bytes(info->fieldset,"Tire ID",raw+4,3*2); + fieldset_add_float(info->fieldset,"Pressure kpa",kpa,2); + fieldset_add_int(info->fieldset,"Temperature C",temp_c,8); return true; } ProtoViewDecoder SchraderEG53MA4TPMSDecoder = { - "Schrader EG53MA4 TPMS", decode + .name = "Schrader EG53MA4 TPMS", + .decode = decode, + .get_fields = NULL, + .build_message = NULL }; diff --git a/applications/plugins/protoview/protocols/tpms/toyota.c b/applications/plugins/protoview/protocols/tpms/toyota.c index b273537395..b9dd1d9598 100644 --- a/applications/plugins/protoview/protocols/tpms/toyota.c +++ b/applications/plugins/protoview/protocols/tpms/toyota.c @@ -42,6 +42,7 @@ static bool decode(uint8_t *bits, uint32_t numbytes, uint32_t numbits, ProtoView for (j = 0; sync[j]; j++) { off = bitmap_seek_bits(bits,numbytes,0,numbits,sync[j]); if (off != BITMAP_SEEK_NOT_FOUND) { + info->start_off = off; off += strlen(sync[j])-2; break; } @@ -58,20 +59,31 @@ static bool decode(uint8_t *bits, uint32_t numbytes, uint32_t numbits, ProtoView if (decoded < 8*9) return false; /* Require the full 8 bytes. */ if (crc8(raw,8,0x80,7) != raw[8]) return false; /* Require sane CRC. */ - float kpa = (float)((raw[4]&0x7f)<<1 | raw[5]>>7) * 0.25 - 7; + /* We detected a valid signal. However now info->start_off is actually + * pointing to the sync part, not the preamble of alternating 0 and 1. + * Protoview decoders get called with some space to the left, in order + * for the decoder itself to fix the signal if neeeded, so that its + * logical representation will be more accurate and better to save + * and retransmit. */ + if (info->start_off >= 12) { + info->start_off -= 12; + bitmap_set_pattern(bits,numbytes,info->start_off,"010101010101"); + } + + info->pulses_count = (off+8*9*2) - info->start_off; + + float psi = (float)((raw[4]&0x7f)<<1 | raw[5]>>7) * 0.25 - 7; int temp = ((raw[5]&0x7f)<<1 | raw[6]>>7) - 40; - snprintf(info->name,sizeof(info->name),"%s","Toyota TPMS"); - snprintf(info->raw,sizeof(info->raw),"%02X%02X%02X%02X%02X%02X%02X%02X%02X", - raw[0],raw[1],raw[2],raw[3],raw[4],raw[5], - raw[6],raw[7],raw[8]); - snprintf(info->info1,sizeof(info->info1),"Tire ID %02X%02X%02X%02X", - raw[0],raw[1],raw[2],raw[3]); - snprintf(info->info1,sizeof(info->info1),"Pressure %.2f psi", (double)kpa); - snprintf(info->info2,sizeof(info->info2),"Temperature %d C", temp); + fieldset_add_bytes(info->fieldset,"Tire ID",raw,4*2); + fieldset_add_float(info->fieldset,"Pressure psi",psi,2); + fieldset_add_int(info->fieldset,"Temperature C",temp,8); return true; } ProtoViewDecoder ToyotaTPMSDecoder = { - "Toyota TPMS", decode + .name = "Toyota TPMS", + .decode = decode, + .get_fields = NULL, + .build_message = NULL }; diff --git a/applications/plugins/protoview/app_buffer.c b/applications/plugins/protoview/raw_samples.c similarity index 70% rename from applications/plugins/protoview/app_buffer.c rename to applications/plugins/protoview/raw_samples.c index 7c069fd91f..f83cca3619 100644 --- a/applications/plugins/protoview/app_buffer.c +++ b/applications/plugins/protoview/raw_samples.c @@ -5,7 +5,7 @@ #include #include #include -#include "app_buffer.h" +#include "raw_samples.h" /* Allocate and initialize a samples buffer. */ RawSamplesBuffer *raw_samples_alloc(void) { @@ -48,6 +48,31 @@ void raw_samples_add(RawSamplesBuffer *s, bool level, uint32_t dur) { furi_mutex_release(s->mutex); } +/* This is like raw_samples_add(), however in case a sample of the + * same level of the previous one is added, the duration of the last + * sample is updated instead. Needed mainly for the decoders build_message() + * methods: it is simpler to write an encoder of a signal like that, + * just creating messages piece by piece. + * + * This function is a bit slower so the internal data sampling should + * be performed with raw_samples_add(). */ +void raw_samples_add_or_update(RawSamplesBuffer *s, bool level, uint32_t dur) { + furi_mutex_acquire(s->mutex,FuriWaitForever); + uint32_t previdx = (s->idx-1) % RAW_SAMPLES_NUM; + if (s->samples[previdx].level == level && + s->samples[previdx].dur != 0) + { + /* Update the last sample: it has the same level. */ + s->samples[previdx].dur += dur; + } else { + /* Add a new sample. */ + s->samples[s->idx].level = level; + s->samples[s->idx].dur = dur; + s->idx = (s->idx+1) % RAW_SAMPLES_NUM; + } + furi_mutex_release(s->mutex); +} + /* Get the sample from the buffer. It is possible to use out of range indexes * as 'idx' because the modulo operation will rewind back from the start. */ void raw_samples_get(RawSamplesBuffer *s, uint32_t idx, bool *level, uint32_t *dur) diff --git a/applications/plugins/protoview/app_buffer.h b/applications/plugins/protoview/raw_samples.h similarity index 94% rename from applications/plugins/protoview/app_buffer.h rename to applications/plugins/protoview/raw_samples.h index 3a34d50f8d..0b04220257 100644 --- a/applications/plugins/protoview/app_buffer.h +++ b/applications/plugins/protoview/raw_samples.h @@ -26,6 +26,7 @@ RawSamplesBuffer *raw_samples_alloc(void); void raw_samples_reset(RawSamplesBuffer *s); void raw_samples_center(RawSamplesBuffer *s, uint32_t offset); void raw_samples_add(RawSamplesBuffer *s, bool level, uint32_t dur); +void raw_samples_add_or_update(RawSamplesBuffer *s, bool level, uint32_t dur); void raw_samples_get(RawSamplesBuffer *s, uint32_t idx, bool *level, uint32_t *dur); void raw_samples_copy(RawSamplesBuffer *dst, RawSamplesBuffer *src); void raw_samples_free(RawSamplesBuffer *s); diff --git a/applications/plugins/protoview/signal.c b/applications/plugins/protoview/signal.c index 06e2197c24..f4c5ebedf3 100644 --- a/applications/plugins/protoview/signal.c +++ b/applications/plugins/protoview/signal.c @@ -4,7 +4,6 @@ #include "app.h" bool decode_signal(RawSamplesBuffer *s, uint64_t len, ProtoViewMsgInfo *info); -void initialize_msg_info(ProtoViewMsgInfo *i); /* ============================================================================= * Raw signal detection @@ -23,6 +22,8 @@ void reset_current_signal(ProtoViewApp *app) { app->signal_decoded = false; raw_samples_reset(DetectedSamples); raw_samples_reset(RawSamples); + free_msg_info(app->msg_info); + app->msg_info = NULL; } /* This function starts scanning samples at offset idx looking for the @@ -119,15 +120,40 @@ uint32_t search_coherent_signal(RawSamplesBuffer *s, uint32_t idx) { return len; } -/* Search the buffer with the stored signal (last N samples received) +/* Called when we detect a message. Just blinks when the message was + * not decoded. Vibrates, too, when the message was correctly decoded. */ +void notify_signal_detected(ProtoViewApp *app, bool decoded) { + static const NotificationSequence decoded_seq = { + &message_vibro_on, + &message_green_255, + &message_delay_50, + &message_green_0, + &message_vibro_off, + NULL + }; + + static const NotificationSequence unknown_seq = { + &message_red_255, + &message_delay_50, + &message_red_0, + NULL + }; + + if (decoded) + notification_message(app->notification, &decoded_seq); + else + notification_message(app->notification, &unknown_seq); +} + +/* Search the source buffer with the stored signal (last N samples received) * in order to find a coherent signal. If a signal that does not appear to * be just noise is found, it is set in DetectedSamples global signal * buffer, that is what is rendered on the screen. */ -void scan_for_signal(ProtoViewApp *app) { - /* We need to work on a copy: the RawSamples buffer is populated +void scan_for_signal(ProtoViewApp *app, RawSamplesBuffer *source) { + /* We need to work on a copy: the source buffer may be populated * by the background thread receiving data. */ RawSamplesBuffer *copy = raw_samples_alloc(); - raw_samples_copy(copy,RawSamples); + raw_samples_copy(copy,source); /* Try to seek on data that looks to have a regular high low high low * pattern. */ @@ -135,7 +161,6 @@ void scan_for_signal(ProtoViewApp *app) { than a few samples it's very easy to mistake noise for signal. */ - ProtoViewMsgInfo *info = malloc(sizeof(ProtoViewMsgInfo)); uint32_t i = 0; while (i < copy->total-1) { @@ -143,10 +168,16 @@ void scan_for_signal(ProtoViewApp *app) { /* For messages that are long enough, attempt decoding. */ if (thislen > minlen) { - initialize_msg_info(info); + /* Allocate the message information that some decoder may + * fill, in case it is able to decode a message. */ + ProtoViewMsgInfo *info = malloc(sizeof(ProtoViewMsgInfo)); + init_msg_info(info,app); + info->short_pulse_dur = copy->short_pulse_dur; + uint32_t saved_idx = copy->idx; /* Save index, see later. */ + /* decode_signal() expects the detected signal to start - * from index .*/ + * from index zero .*/ raw_samples_center(copy,i); bool decoded = decode_signal(copy,thislen,info); copy->idx = saved_idx; /* Restore the index as we are scanning @@ -158,7 +189,8 @@ void scan_for_signal(ProtoViewApp *app) { if ((thislen > app->signal_bestlen && app->signal_decoded == false) || (app->signal_decoded == false && decoded)) { - app->signal_info = *info; + free_msg_info(app->msg_info); + app->msg_info = info; app->signal_bestlen = thislen; app->signal_decoded = decoded; raw_samples_copy(DetectedSamples,copy); @@ -166,18 +198,17 @@ void scan_for_signal(ProtoViewApp *app) { FURI_LOG_E(TAG, "===> Displayed sample updated (%d samples %lu us)", (int)thislen, DetectedSamples->short_pulse_dur); - /* Adjust raw view scale if the signal has an high - * data rate. */ - if (DetectedSamples->short_pulse_dur < 75) - app->us_scale = 10; - else if (DetectedSamples->short_pulse_dur < 145) - app->us_scale = 30; + adjust_raw_view_scale(app,DetectedSamples->short_pulse_dur); + notify_signal_detected(app,decoded); + } else { + /* If the structure was not filled, discard it. Otherwise + * now the owner is app->msg_info. */ + free_msg_info(info); } } i += thislen ? thislen : 1; } raw_samples_free(copy); - free(info); } /* ============================================================================= @@ -215,10 +246,104 @@ bool bitmap_get(uint8_t *b, uint32_t blen, uint32_t bitpos) { return (b[byte] & (1< 8 && didx < dlen && sidx < slen) { + d[didx++] = s[sidx++]; + count -= 8; + } + doff = didx * 8; + soff = sidx * 8; + /* Note that if we entered this path, the count at the end + * of the loop will be < 8. */ + } + + /* Copy the bits needed to reach an offset where we can copy + * two half bytes of src to a full byte of destination. */ + while(count > 8 && (doff&7) != 0) { + bool bit = bitmap_get(s,slen,soff++); + bitmap_set(d,dlen,doff++,bit); + count--; + } + + /* If we are here and count > 8, we have an offset that is byte aligned + * to the destination bitmap, but not aligned to the source bitmap. + * We can copy fast enough by shifting each two bytes of the original + * bitmap. + * + * This is how it works: + * + * dst: + * +--------+--------+--------+ + * | 0 | 1 | 2 | + * | | | | <- data to fill + * +--------+--------+--------+ + * ^ + * | + * doff = 8 + * + * src: + * +--------+--------+--------+ + * | 0 | 1 | 2 | + * |hellowor|ld!HELLO|WORLDS!!| <- data to copy + * +--------+--------+--------+ + * ^ + * | + * soff = 11 + * + * skew = 11%8 = 3 + * each destination byte in dst will receive: + * + * dst[doff/8] = (src[soff/8] << skew) | (src[soff/8+1] >> (8-skew)) + * + * dstbyte = doff/8 = 8/8 = 1 + * srcbyte = soff/8 = 11/8 = 1 + * + * so dst[1] will get: + * src[1] << 3, that is "ld!HELLO" << 3 = "HELLO..." + * xored with + * src[2] << 5, that is "WORLDS!!" >> 5 = ".....WOR" + * That is "HELLOWOR" + */ + if (count > 8) { + uint8_t skew = soff % 8; /* Don't worry, compiler will optimize. */ + uint32_t didx = doff/8; + uint32_t sidx = soff/8; + while(count > 8 && didx < dlen && sidx < slen) { + d[didx] = ((s[sidx] << skew) | + (s[sidx+1] >> (8-skew))); + sidx++; + didx++; + soff += 8; + doff += 8; + count -= 8; + } + } + + /* Here count is guaranteed to be < 8. + * Copy the final bits bit by bit. */ + while(count) { + bool bit = bitmap_get(s,slen,soff++); + bitmap_set(d,dlen,doff++,bit); + count--; + } +} + /* We decode bits assuming the first bit we receive is the MSB * (see bitmap_set/get functions). Certain devices send data * encoded in the reverse way. */ -void bitmap_reverse_bytes(uint8_t *p, uint32_t len) { +void bitmap_reverse_bytes_bits(uint8_t *p, uint32_t len) { for (uint32_t j = 0; j < len; j++) { uint32_t b = p[j]; /* Step 1: swap the two nibbles: 12345678 -> 56781234 */ @@ -259,15 +384,17 @@ uint32_t bitmap_seek_bits(uint8_t *b, uint32_t blen, uint32_t startpos, uint32_t return BITMAP_SEEK_NOT_FOUND; } -/* Set the pattern 'pat' into the bitmap 'b' of max length 'blen' bytes. +/* Set the pattern 'pat' into the bitmap 'b' of max length 'blen' bytes, + * starting from the specified offset. + * * The pattern is given as a string of 0s and 1s characters, like "01101001". * This function is useful in order to set the test vectors in the protocol * decoders, to see if the decoding works regardless of the fact we are able * to actually receive a given signal. */ -void bitmap_set_pattern(uint8_t *b, uint32_t blen, const char *pat) { +void bitmap_set_pattern(uint8_t *b, uint32_t blen, uint32_t off, const char *pat) { uint32_t i = 0; while(pat[i]) { - bitmap_set(b,blen,i,pat[i] == '1'); + bitmap_set(b,blen,i+off,pat[i] == '1'); i++; } } @@ -408,10 +535,21 @@ ProtoViewDecoder *Decoders[] = { NULL }; +/* Free the message info and allocated data. */ +void free_msg_info(ProtoViewMsgInfo *i) { + if (i == NULL) return; + fieldset_free(i->fieldset); + free(i->bits); + free(i); +} + /* Reset the message info structure before passing it to the decoding * functions. */ -void initialize_msg_info(ProtoViewMsgInfo *i) { +void init_msg_info(ProtoViewMsgInfo *i, ProtoViewApp *app) { + UNUSED(app); memset(i,0,sizeof(ProtoViewMsgInfo)); + i->bits = NULL; + i->fieldset = fieldset_new(); } /* This function is called when a new signal is detected. It converts it @@ -424,7 +562,7 @@ bool decode_signal(RawSamplesBuffer *s, uint64_t len, ProtoViewMsgInfo *info) { /* We call the decoders with an offset a few samples before the actual * signal detected and for a len of a few bits after its end. */ - uint32_t before_samples = 20; + uint32_t before_samples = 32; uint32_t after_samples = 100; uint8_t *bitmap = malloc(bitmap_size); @@ -451,14 +589,28 @@ bool decode_signal(RawSamplesBuffer *s, uint64_t len, ProtoViewMsgInfo *info) { uint32_t delta = furi_get_tick() - start_time; FURI_LOG_E(TAG, "Decoder %s took %lu ms", Decoders[j]->name, (unsigned long)delta); - if (decoded) break; + if (decoded) { + info->decoder = Decoders[j]; + break; + } j++; } if (!decoded) { FURI_LOG_E(TAG, "No decoding possible"); } else { - FURI_LOG_E(TAG, "Decoded %s, raw=%s info=[%s,%s,%s,%s]", info->name, info->raw, info->info1, info->info2, info->info3, info->info4); + FURI_LOG_E(TAG, "+++ Decoded %s", info->decoder->name); + /* The message was correctly decoded: fill the info structure + * with the decoded signal. The decoder may not implement offset/len + * filling of the structure. In such case we have no info and + * pulses_count will be set to zero. */ + if (info->pulses_count) { + info->bits_bytes = (info->pulses_count+7)/8; // Round to full byte. + info->bits = malloc(info->bits_bytes); + bitmap_copy(info->bits,info->bits_bytes,0, + bitmap,bitmap_size,info->start_off, + info->pulses_count); + } } free(bitmap); return decoded; diff --git a/applications/plugins/protoview/signal_file.c b/applications/plugins/protoview/signal_file.c new file mode 100644 index 0000000000..31c8726fb0 --- /dev/null +++ b/applications/plugins/protoview/signal_file.c @@ -0,0 +1,141 @@ +/* Copyright (C) 2023 Salvatore Sanfilippo -- All Rights Reserved + * Copyright (C) 2023 Maciej Wojtasik -- All Rights Reserved + * See the LICENSE file for information about the license. */ + +#include "app.h" +#include +#include + +/* ========================= Signal file operations ========================= */ + +/* This function saves the current logical signal on disk. What is saved here + * is not the signal as level and duration as we received it from CC1101, + * but it's logical representation stored in the app->msg_info bitmap, where + * each 1 or 0 means a puls or gap for the specified short pulse duration time + * (te). */ +bool save_signal(ProtoViewApp *app, const char *filename) { + /* We have a message at all? */ + if (app->msg_info == NULL || app->msg_info->pulses_count == 0) return false; + + Storage *storage = furi_record_open(RECORD_STORAGE); + FlipperFormat *file = flipper_format_file_alloc(storage); + Stream *stream = flipper_format_get_raw_stream(file); + FuriString *file_content = NULL; + bool success = true; + + if (flipper_format_file_open_always(file, filename)) { + /* Write the file header. */ + FuriString *file_content = furi_string_alloc(); + const char *preset_id = ProtoViewModulations[app->modulation].id; + + furi_string_printf(file_content, + "Filetype: Flipper SubGhz RAW File\n" + "Version: 1\n" + "Frequency: %ld\n" + "Preset: %s\n", + app->frequency, + preset_id ? preset_id : "FuriHalSubGhzPresetCustom"); + + /* For custom modulations, we need to emit a set of registers. */ + if (preset_id == NULL) { + FuriString *custom = furi_string_alloc(); + uint8_t *regs = ProtoViewModulations[app->modulation].custom; + furi_string_printf(custom, + "Custom_preset_module: CC1101\n" + "Custom_preset_data: "); + for (int j = 0; regs[j]; j += 2) { + furi_string_cat_printf(custom, "%02X %02X ", + (int)regs[j], (int)regs[j+1]); + } + size_t len = furi_string_size(file_content); + furi_string_set_char(custom,len-1,'\n'); + furi_string_cat(file_content,custom); + furi_string_free(custom); + } + + /* We always save raw files. */ + furi_string_cat_printf(file_content, + "Protocol: RAW\n" + "RAW_Data: -10000\n"); // Start with 10 ms of gap + + /* Write header. */ + size_t len = furi_string_size(file_content); + if (stream_write(stream, + (uint8_t*) furi_string_get_cstr(file_content), len) + != len) + { + FURI_LOG_W(TAG, "Short write to file"); + success = false; + goto write_err; + } + furi_string_reset(file_content); + + /* Write raw data sections. The Flipper subghz parser can't handle + * too much data on a single line, so we generate a new one + * every few samples. */ + uint32_t this_line_samples = 0; + uint32_t max_line_samples = 100; + uint32_t idx = 0; // Iindex in the signal bitmap. + ProtoViewMsgInfo *i = app->msg_info; + while(idx < i->pulses_count) { + bool level = bitmap_get(i->bits,i->bits_bytes,idx); + uint32_t te_times = 1; + idx++; + /* Count the duration of the current pulse/gap. */ + while(idx < i->pulses_count && + bitmap_get(i->bits,i->bits_bytes,idx) == level) + { + te_times++; + idx++; + } + // Invariant: after the loop 'idx' is at the start of the + // next gap or pulse. + + int32_t dur = (int32_t)i->short_pulse_dur * te_times; + if (level == 0) dur = -dur; /* Negative is gap in raw files. */ + + /* Emit the sample. If this is the first sample of the line, + * also emit the RAW_Data: field. */ + if (this_line_samples == 0) + furi_string_cat_printf(file_content,"RAW_Data: "); + furi_string_cat_printf(file_content,"%d ",(int)dur); + this_line_samples++; + + /* Store the current set of samples on disk, when we reach a + * given number or the end of the signal. */ + bool end_reached = (idx == i->pulses_count); + if (this_line_samples == max_line_samples || end_reached) { + /* If that's the end, terminate the signal with a long + * gap. */ + if (end_reached) furi_string_cat_printf(file_content,"-10000 "); + + /* We always have a trailing space in the last sample. Make it + * a newline. */ + size_t len = furi_string_size(file_content); + furi_string_set_char(file_content,len-1,'\n'); + + if (stream_write(stream, + (uint8_t*) furi_string_get_cstr(file_content), + len) != len) + { + FURI_LOG_W(TAG, "Short write to file"); + success = false; + goto write_err; + } + + /* Prepare for next line. */ + furi_string_reset(file_content); + this_line_samples = 0; + } + } + } else { + success = false; + FURI_LOG_W(TAG, "Unable to open file"); + } + +write_err: + furi_record_close(RECORD_STORAGE); + flipper_format_free(file); + if (file_content != NULL) furi_string_free(file_content); + return success; +} diff --git a/applications/plugins/protoview/ui.c b/applications/plugins/protoview/ui.c index e22e4d57ee..8badab5bf8 100644 --- a/applications/plugins/protoview/ui.c +++ b/applications/plugins/protoview/ui.c @@ -3,6 +3,122 @@ #include "app.h" +/* =========================== Subview handling ================================ + * Note that these are not the Flipper subviews, but the subview system + * implemented inside ProtoView. + * ========================================================================== */ + +/* Return the ID of the currently selected subview, of the current + * view. */ +int ui_get_current_subview(ProtoViewApp *app) { + return app->current_subview[app->current_view]; +} + +/* Called by view rendering callback that has subviews, to show small triangles + * facing down/up if there are other subviews the user can access with up + * and down. */ +void ui_show_available_subviews(Canvas *canvas, ProtoViewApp *app, + int last_subview) +{ + int subview = ui_get_current_subview(app); + if (subview != 0) + canvas_draw_triangle(canvas,120,5,8,5,CanvasDirectionBottomToTop); + if (subview != last_subview-1) + canvas_draw_triangle(canvas,120,59,8,5,CanvasDirectionTopToBottom); +} + +/* Handle up/down keys when we are in a subview. If the function catched + * such keypress, it returns true, so that the actual view input callback + * knows it can just return ASAP without doing anything. */ +bool ui_process_subview_updown(ProtoViewApp *app, InputEvent input, int last_subview) { + int subview = ui_get_current_subview(app); + if (input.type == InputTypePress) { + if (input.key == InputKeyUp) { + if (subview != 0) + app->current_subview[app->current_view]--; + return true; + } else if (input.key == InputKeyDown) { + if (subview != last_subview-1) + app->current_subview[app->current_view]++; + return true; + } + } + return false; +} + +/* ============================= Text input ==================================== + * Normally we just use our own private UI widgets. However for the text input + * widget, that is quite complex, visualizes a keyboard and must be standardized + * for user coherent experience, we use the one provided by the Flipper + * framework. The following two functions allow to show the keyboard to get + * text and later dismiss it. + * ========================================================================== */ + +/* Show the keyboard, take the user input and store it into the specified + * 'buffer' of 'buflen' total bytes. When the user is done, the done_callback + * is called passing the application context to it. Such callback needs + * to do whatever it wants with the input buffer and dismissi the keyboard + * calling: dismiss_keyboard(app); + * + * Note: if the buffer is not a null-termined zero string, what it contains will + * be used as initial input for the user. */ +void ui_show_keyboard(ProtoViewApp *app, char *buffer, uint32_t buflen, + void (*done_callback)(void*)) +{ + app->show_text_input = true; + app->text_input_buffer = buffer; + app->text_input_buffer_len = buflen; + app->text_input_done_callback = done_callback; +} + +void ui_dismiss_keyboard(ProtoViewApp *app) { + view_dispatcher_stop(app->view_dispatcher); +} + +/* ================================= Alert ================================== */ + +/* Set an alert message to be shown over any currently active view, for + * the specified amount of time of 'ttl' milliseconds. */ +void ui_show_alert(ProtoViewApp *app, const char *text, uint32_t ttl) { + app->alert_dismiss_time = furi_get_tick() + furi_ms_to_ticks(ttl); + snprintf(app->alert_text,ALERT_MAX_LEN,"%s",text); +} + +/* Cancel the alert before its time has elapsed. */ +void ui_dismiss_alert(ProtoViewApp *app) { + app->alert_dismiss_time = 0; +} + +/* Show the alert if an alert is set. This is called after the currently + * active view displayed its stuff, so we overwrite the screen with the + * alert message. */ +void ui_draw_alert_if_needed(Canvas *canvas, ProtoViewApp *app) { + if (app->alert_dismiss_time == 0) { + /* No active alert. */ + return; + } else if (app->alert_dismiss_time < furi_get_tick()) { + /* Alert just expired. */ + ui_dismiss_alert(app); + return; + } + + /* Show the alert. A box with black border and a text inside. */ + canvas_set_font(canvas, FontPrimary); + uint8_t w = canvas_string_width(canvas, app->alert_text); + uint8_t h = 8; // Font height. + uint8_t text_x = 64-(w/2); + uint8_t text_y = 32+4; + uint8_t padding = 3; + canvas_set_color(canvas,ColorBlack); + canvas_draw_box(canvas,text_x-padding,text_y-padding-h,w+padding*2,h+padding*2); + canvas_set_color(canvas,ColorWhite); + canvas_draw_box(canvas,text_x-padding+1,text_y-padding-h+1,w+padding*2-2,h+padding*2-2); + canvas_set_color(canvas,ColorBlack); + canvas_draw_str(canvas,text_x,text_y,app->alert_text); +} + +/* =========================== Canvas extensions ============================ */ + void canvas_draw_str_with_border(Canvas* canvas, uint8_t x, uint8_t y, const char* str, Color text_color, Color border_color) { struct { diff --git a/applications/plugins/protoview/view_build.c b/applications/plugins/protoview/view_build.c new file mode 100644 index 0000000000..fd276b61d6 --- /dev/null +++ b/applications/plugins/protoview/view_build.c @@ -0,0 +1,253 @@ +/* Copyright (C) 2022-2023 Salvatore Sanfilippo -- All Rights Reserved + * See the LICENSE file for information about the license. */ + +#include "app.h" + +extern ProtoViewDecoder *Decoders[]; // Defined in signal.c. + +/* Our view private data. */ +#define USER_VALUE_LEN 64 +typedef struct { + ProtoViewDecoder *decoder; /* Decoder we are using to create a + message. */ + uint32_t cur_decoder; /* Decoder index when we are yet selecting + a decoder. Used when decoder is NULL. */ + ProtoViewFieldSet *fieldset; /* The fields to populate. */ + uint32_t cur_field; /* Field we are editing right now. This + is the index inside the 'fieldset' + fields. */ + char *user_value; /* Keyboard input to replace the current + field value goes here. */ +} BuildViewPrivData; + +/* Not all the decoders support message bulding, so we can't just + * increment / decrement the cur_decoder index here. */ +static void select_next_decoder(ProtoViewApp *app) { + BuildViewPrivData *privdata = app->view_privdata; + do { + privdata->cur_decoder++; + if (Decoders[privdata->cur_decoder] == NULL) + privdata->cur_decoder = 0; + } while(Decoders[privdata->cur_decoder]->get_fields == NULL); +} + +/* Like select_next_decoder() but goes backward. */ +static void select_prev_decoder(ProtoViewApp *app) { + BuildViewPrivData *privdata = app->view_privdata; + do { + if (privdata->cur_decoder == 0) { + /* Go one after the last one to wrap around. */ + while(Decoders[privdata->cur_decoder]) privdata->cur_decoder++; + } + privdata->cur_decoder--; + } while(Decoders[privdata->cur_decoder]->get_fields == NULL); +} + +/* Render the view to select the decoder, among the ones that + * support message building. */ +static void render_view_select_decoder(Canvas *const canvas, ProtoViewApp *app) { + BuildViewPrivData *privdata = app->view_privdata; + canvas_set_font(canvas, FontPrimary); + canvas_draw_str(canvas, 0, 9, "Signal creator"); + canvas_set_font(canvas, FontSecondary); + canvas_draw_str(canvas, 0, 19, "up/down: select, ok: choose"); + + canvas_set_font(canvas, FontPrimary); + canvas_draw_str_aligned(canvas,64,38,AlignCenter,AlignCenter, + Decoders[privdata->cur_decoder]->name); +} + +/* Render the view that allows the user to populate the fields needed + * for the selected decoder to build a message. */ +static void render_view_set_fields(Canvas *const canvas, ProtoViewApp *app) { + BuildViewPrivData *privdata = app->view_privdata; + char buf[32]; + snprintf(buf,sizeof(buf), "%s field %d/%d", + privdata->decoder->name, (int)privdata->cur_field+1, + (int)privdata->fieldset->numfields); + canvas_set_color(canvas,ColorBlack); + canvas_draw_box(canvas,0,0,128,21); + canvas_set_color(canvas,ColorWhite); + canvas_set_font(canvas, FontPrimary); + canvas_draw_str(canvas, 1, 9, buf); + canvas_set_font(canvas, FontSecondary); + canvas_draw_str(canvas, 1, 19, "up/down: next field, ok: edit"); + + /* Write the field name, type, current content. */ + canvas_set_color(canvas,ColorBlack); + ProtoViewField *field = privdata->fieldset->fields[privdata->cur_field]; + snprintf(buf,sizeof(buf), "%s %s:%d", field->name, + field_get_type_name(field), (int)field->len); + buf[0] = toupper(buf[0]); + canvas_set_font(canvas, FontPrimary); + canvas_draw_str_aligned(canvas,64,30,AlignCenter,AlignCenter,buf); + canvas_set_font(canvas, FontSecondary); + + /* Render the current value between "" */ + unsigned int written = (unsigned int) field_to_string(buf+1,sizeof(buf)-1,field); + buf[0] = '"'; + if (written+3 < sizeof(buf)) memcpy(buf+written+1,"\"\x00",2); + canvas_draw_str_aligned(canvas,63,45,AlignCenter,AlignCenter,buf); + + /* Footer instructions. */ + canvas_draw_str(canvas, 0, 62, "Long ok: create, < > incr/decr"); +} + +/* Render the build message view. */ +void render_view_build_message(Canvas *const canvas, ProtoViewApp *app) { + BuildViewPrivData *privdata = app->view_privdata; + + if (privdata->decoder) + render_view_set_fields(canvas,app); + else + render_view_select_decoder(canvas,app); +} + +/* Handle input for the decoder selection. */ +static void process_input_select_decoder(ProtoViewApp *app, InputEvent input) { + BuildViewPrivData *privdata = app->view_privdata; + if (input.type == InputTypeShort) { + if (input.key == InputKeyOk) { + privdata->decoder = Decoders[privdata->cur_decoder]; + privdata->fieldset = fieldset_new(); + privdata->decoder->get_fields(privdata->fieldset); + + /* If the currently decoded message was produced with the + * same decoder the user selected, let's populate the + * defaults with the current values. So the user will + * actaully edit the current message. */ + if (app->signal_decoded && + app->msg_info->decoder == privdata->decoder) + { + fieldset_copy_matching_fields(privdata->fieldset, + app->msg_info->fieldset); + } + + /* Now we use the subview system in order to protect the + message editing mode from accidental < or > presses. + Since we are technically into a subview now, we'll have + control of < and >. */ + InputEvent ii = {.type = InputTypePress, .key = InputKeyDown}; + ui_process_subview_updown(app,ii,2); + } else if (input.key == InputKeyDown) { + select_next_decoder(app); + } else if (input.key == InputKeyUp) { + select_prev_decoder(app); + } + } +} + +/* Called after the user typed the new field value in the keyboard. + * Let's save it and remove the keyboard view. */ +static void text_input_done_callback(void* context) { + ProtoViewApp *app = context; + BuildViewPrivData *privdata = app->view_privdata; + + if (field_set_from_string(privdata->fieldset->fields[privdata->cur_field], + privdata->user_value, strlen(privdata->user_value)) == false) + { + ui_show_alert(app, "Invalid value", 1500); + } + + free(privdata->user_value); + privdata->user_value = NULL; + ui_dismiss_keyboard(app); +} + +/* Handles the effects of < and > keys in field editing mode. + * Instead of force the user to enter the text input mode, delete + * the old value, enter the one, we allow to increment and + * decrement the current field in a much simpler way. + * + * The current filed is changed by 'incr' amount. */ +static bool increment_current_field(ProtoViewApp *app, int incr) { + BuildViewPrivData *privdata = app->view_privdata; + ProtoViewFieldSet *fs = privdata->fieldset; + ProtoViewField *f = fs->fields[privdata->cur_field]; + return field_incr_value(f,incr); +} + +/* Handle input for fields editing mode. */ +static void process_input_set_fields(ProtoViewApp *app, InputEvent input) { + BuildViewPrivData *privdata = app->view_privdata; + ProtoViewFieldSet *fs = privdata->fieldset; + + if (input.type == InputTypeShort && input.key == InputKeyOk) { + /* Show the keyboard to let the user type the new + * value. */ + if (privdata->user_value == NULL) + privdata->user_value = malloc(USER_VALUE_LEN); + field_to_string(privdata->user_value, USER_VALUE_LEN, + fs->fields[privdata->cur_field]); + ui_show_keyboard(app, privdata->user_value, USER_VALUE_LEN, + text_input_done_callback); + } else if (input.type == InputTypeShort && input.key == InputKeyDown) { + privdata->cur_field = (privdata->cur_field+1) % fs->numfields; + } else if (input.type == InputTypeShort && input.key == InputKeyUp) { + if (privdata->cur_field == 0) + privdata->cur_field = fs->numfields-1; + else + privdata->cur_field--; + } else if (input.type == InputTypeShort && input.key == InputKeyRight) { + increment_current_field(app,1); + } else if (input.type == InputTypeShort && input.key == InputKeyLeft) { + increment_current_field(app,-1); + } else if (input.type == InputTypeRepeat && input.key == InputKeyRight) { + // The reason why we don't use a large increment directly + // is that certain field types only support +1 -1 increments. + int times = 10; + while(times--) increment_current_field(app,1); + } else if (input.type == InputTypeRepeat && input.key == InputKeyLeft) { + int times = 10; + while(times--) increment_current_field(app,-1); + } else if (input.type == InputTypeLong && input.key == InputKeyOk) { + // Build the message in a fresh raw buffer. + if (privdata->decoder->build_message) { + RawSamplesBuffer *rs = raw_samples_alloc(); + privdata->decoder->build_message(rs,privdata->fieldset); + app->signal_decoded = false; // So that the new signal will be + // accepted as the current signal. + scan_for_signal(app,rs); + raw_samples_free(rs); + ui_show_alert(app,"Done: press back key",3000); + } + } +} + +/* Handle input for the build message view. */ +void process_input_build_message(ProtoViewApp *app, InputEvent input) { + BuildViewPrivData *privdata = app->view_privdata; + if (privdata->decoder) + process_input_set_fields(app,input); + else + process_input_select_decoder(app,input); +} + +/* Enter view callback. */ +void view_enter_build_message(ProtoViewApp *app) { + BuildViewPrivData *privdata = app->view_privdata; + + // When we enter the view, the current decoder is just set to zero. + // Seek the next valid if needed. + if (Decoders[privdata->cur_decoder]->get_fields == NULL) { + select_next_decoder(app); + } + + // However if there is currently a decoded message, and the + // decoder of such message supports message building, let's + // select it. + if (app->signal_decoded && + app->msg_info->decoder->get_fields && + app->msg_info->decoder->build_message) + { + while(Decoders[privdata->cur_decoder] != app->msg_info->decoder) + select_next_decoder(app); + } +} + +/* Called on exit for cleanup. */ +void view_exit_build_message(ProtoViewApp *app) { + BuildViewPrivData *privdata = app->view_privdata; + if (privdata->fieldset) fieldset_free(privdata->fieldset); + if (privdata->user_value) free(privdata->user_value); +} diff --git a/applications/plugins/protoview/view_info.c b/applications/plugins/protoview/view_info.c index 775c8abc2b..6aa69739c5 100644 --- a/applications/plugins/protoview/view_info.c +++ b/applications/plugins/protoview/view_info.c @@ -2,8 +2,122 @@ * See the LICENSE file for information about the license. */ #include "app.h" +#include +#include -/* Renders the view with the detected message information. */ +/* This view has subviews accessible navigating up/down. This + * enumaration is used to track the currently active subview. */ +enum { + SubViewInfoMain, + SubViewInfoSave, + SubViewInfoLast, /* Just a sentinel. */ +}; + +/* Our view private data. */ +#define SAVE_FILENAME_LEN 64 +typedef struct { + /* Our save view displays an oscilloscope-alike resampled signal, + * so that the user can see what they are saving. With left/right + * you can move to next rows. Here we store where we are. */ + uint32_t signal_display_start_row; + char *filename; + uint8_t cur_info_page; // Info page to display. Useful when there are + // too many fields populated by the decoder that + // a single page is not enough. +} InfoViewPrivData; + +/* Draw the text label and value of the specified info field at x,y. */ +static void render_info_field(Canvas *const canvas, + ProtoViewField *f, uint8_t x, uint8_t y) +{ + char buf[64]; + char strval[32]; + + field_to_string(strval,sizeof(strval),f); + snprintf(buf,sizeof(buf),"%s: %s", f->name, strval); + canvas_set_font(canvas, FontSecondary); + canvas_draw_str(canvas, x, y, buf); +} + +/* Render the view with the detected message information. */ +#define INFO_LINES_PER_PAGE 5 +static void render_subview_main(Canvas *const canvas, ProtoViewApp *app) { + InfoViewPrivData *privdata = app->view_privdata; + uint8_t pages = (app->msg_info->fieldset->numfields + +(INFO_LINES_PER_PAGE-1)) / INFO_LINES_PER_PAGE; + privdata->cur_info_page %= pages; + uint8_t current_page = privdata->cur_info_page; + char buf[32]; + + /* Protocol name as title. */ + canvas_set_font(canvas, FontPrimary); + uint8_t y = 8, lineheight = 10; + + if (pages > 1) { + snprintf(buf,sizeof(buf),"%s %u/%u", app->msg_info->decoder->name, + current_page+1, pages); + canvas_draw_str(canvas, 0, y, buf); + } else { + canvas_draw_str(canvas, 0, y, app->msg_info->decoder->name); + } + y += lineheight; + + /* Draw the info fields. */ + uint8_t max_lines = INFO_LINES_PER_PAGE; + uint32_t j = current_page*max_lines; + while (j < app->msg_info->fieldset->numfields) { + render_info_field(canvas,app->msg_info->fieldset->fields[j++],0,y); + y += lineheight; + if (--max_lines == 0) break; + } + + /* Draw a vertical "save" label. Temporary solution, to switch to + * something better ASAP. */ + y = 37; + lineheight = 7; + canvas_draw_str(canvas, 119, y, "s"); y += lineheight; + canvas_draw_str(canvas, 119, y, "a"); y += lineheight; + canvas_draw_str(canvas, 119, y, "v"); y += lineheight; + canvas_draw_str(canvas, 119, y, "e"); y += lineheight; +} + +/* Render view with save option. */ +static void render_subview_save(Canvas *const canvas, ProtoViewApp *app) { + InfoViewPrivData *privdata = app->view_privdata; + + /* Display our signal in digital form: here we don't show the + * signal with the exact timing of the received samples, but as it + * is in its logic form, in exact multiples of the short pulse length. */ + uint8_t rows = 6; + uint8_t rowheight = 11; + uint8_t bitwidth = 4; + uint8_t bitheight = 5; + uint32_t idx = privdata->signal_display_start_row * (128/4); + bool prevbit = false; + for (uint8_t y = bitheight+12; y <= rows*rowheight; y += rowheight) { + for (uint8_t x = 0; x < 128; x += 4) { + bool bit = bitmap_get(app->msg_info->bits, + app->msg_info->bits_bytes,idx); + uint8_t prevy = y + prevbit*(bitheight*-1) - 1; + uint8_t thisy = y + bit*(bitheight*-1) - 1; + canvas_draw_line(canvas,x,prevy,x,thisy); + canvas_draw_line(canvas,x,thisy,x+bitwidth-1,thisy); + prevbit = bit; + if (idx >= app->msg_info->pulses_count) { + canvas_set_color(canvas, ColorWhite); + canvas_draw_dot(canvas, x+1,thisy); + canvas_draw_dot(canvas, x+3,thisy); + canvas_set_color(canvas, ColorBlack); + } + idx++; // Draw next bit + } + } + + canvas_set_font(canvas, FontSecondary); + canvas_draw_str(canvas, 0, 6, "ok: send, long ok: save"); +} + +/* Render the selected subview of this view. */ void render_view_info(Canvas *const canvas, ProtoViewApp *app) { if (app->signal_decoded == false) { canvas_set_font(canvas, FontSecondary); @@ -11,32 +125,211 @@ void render_view_info(Canvas *const canvas, ProtoViewApp *app) { return; } - /* Protocol name as title. */ - canvas_set_font(canvas, FontPrimary); - uint8_t y = 8, lineheight = 10; - canvas_draw_str(canvas, 0, y, app->signal_info.name); - y += lineheight; + ui_show_available_subviews(canvas,app,SubViewInfoLast); + switch(app->current_subview[app->current_view]) { + case SubViewInfoMain: render_subview_main(canvas,app); break; + case SubViewInfoSave: render_subview_save(canvas,app); break; + } +} - /* Info fields. */ - char buf[128]; - canvas_set_font(canvas, FontSecondary); - if (app->signal_info.raw[0]) { - snprintf(buf,sizeof(buf),"Raw: %s", app->signal_info.raw); - canvas_draw_str(canvas, 0, y, buf); - y += lineheight; +/* The user typed the file name. Let's save it and remove the keyboard + * view. */ +static void text_input_done_callback(void* context) { + ProtoViewApp *app = context; + InfoViewPrivData *privdata = app->view_privdata; + + FuriString *save_path = furi_string_alloc_printf( + "%s/%s.sub", EXT_PATH("subghz"), privdata->filename); + save_signal(app, furi_string_get_cstr(save_path)); + furi_string_free(save_path); + + free(privdata->filename); + privdata->filename = NULL; // Don't free it again on view exit + ui_dismiss_keyboard(app); + ui_show_alert(app, "Signal saved", 1500); +} + +/* Replace all the occurrences of character c1 with c2 in the specified + * string. */ +void str_replace(char *buf, char c1, char c2) { + char *p = buf; + while(*p) { + if (*p == c1) *p = c2; + p++; + } +} + +/* Set a random filename the user can edit. */ +void set_signal_random_filename(ProtoViewApp *app, char *buf, size_t buflen) { + char suffix[6]; + set_random_name(suffix,sizeof(suffix)); + snprintf(buf,buflen,"%.10s-%s-%d",app->msg_info->decoder->name,suffix,rand()%1000); + str_replace(buf,' ','_'); + str_replace(buf,'-','_'); + str_replace(buf,'/','_'); +} + +/* ========================== Signal transmission =========================== */ + +/* This is the context we pass to the data yield callback for + * asynchronous tx. */ +typedef enum { + SendSignalSendStartGap, + SendSignalSendBits, + SendSignalSendEndGap, + SendSignalEndTransmission +} SendSignalState; + +#define PROTOVIEW_SENDSIGNAL_START_GAP 10000 /* microseconds. */ +#define PROTOVIEW_SENDSIGNAL_END_GAP 10000 /* microseconds. */ + +typedef struct { + SendSignalState state; // Current state. + uint32_t curpos; // Current bit position of data to send. + ProtoViewApp *app; // App reference. + uint32_t start_gap_dur; // Gap to send at the start. + uint32_t end_gap_dur; // Gap to send at the end. +} SendSignalCtx; + +/* Setup the state context for the callback responsible to feed data + * to the subghz async tx system. */ +static void send_signal_init(SendSignalCtx *ss, ProtoViewApp *app) { + ss->state = SendSignalSendStartGap; + ss->curpos = 0; + ss->app = app; + ss->start_gap_dur = PROTOVIEW_SENDSIGNAL_START_GAP; + ss->end_gap_dur = PROTOVIEW_SENDSIGNAL_END_GAP; +} + +/* Send signal data feeder callback. When the asynchronous transmission is + * active, this function is called to return new samples from the currently + * decoded signal in app->msg_info. The subghz subsystem aspects this function, + * that is the data feeder, to return LevelDuration types (that is a structure + * with level, that is pulse or gap, and duration in microseconds). + * + * The position into the transmission is stored in the context 'ctx', that + * references a SendSignalCtx structure. + * + * In the SendSignalCtx structure 'ss' we remember at which bit of the + * message we are, in ss->curoff. We also send a start and end gap in order + * to make sure the transmission is clear. + */ +LevelDuration radio_tx_feed_data(void *ctx) { + SendSignalCtx *ss = ctx; + + /* Send start gap. */ + if (ss->state == SendSignalSendStartGap) { + ss->state = SendSignalSendBits; + return level_duration_make(0,ss->start_gap_dur); + } + + /* Send data. */ + if (ss->state == SendSignalSendBits) { + uint32_t dur = 0, j; + uint32_t level = 0; + + /* Let's see how many consecutive bits we have with the same + * level. */ + for (j = 0; ss->curpos+j < ss->app->msg_info->pulses_count; j++) { + uint32_t l = bitmap_get(ss->app->msg_info->bits, + ss->app->msg_info->bits_bytes, + ss->curpos+j); + if (j == 0) { + /* At the first bit of this sequence, we store the + * level of the sequence. */ + level = l; + dur += ss->app->msg_info->short_pulse_dur; + continue; + } + + /* As long as the level is the same, we update the duration. + * Otherwise stop the loop and return this sample. */ + if (l != level) break; + dur += ss->app->msg_info->short_pulse_dur; + } + ss->curpos += j; + + /* If this was the last set of bits, change the state to + * send the final gap. */ + if (ss->curpos >= ss->app->msg_info->pulses_count) + ss->state = SendSignalSendEndGap; + return level_duration_make(level, dur); + } + + /* Send end gap. */ + if (ss->state == SendSignalSendEndGap) { + ss->state = SendSignalEndTransmission; + return level_duration_make(0,ss->end_gap_dur); } - canvas_draw_str(canvas, 0, y, app->signal_info.info1); y += lineheight; - canvas_draw_str(canvas, 0, y, app->signal_info.info2); y += lineheight; - canvas_draw_str(canvas, 0, y, app->signal_info.info3); y += lineheight; - canvas_draw_str(canvas, 0, y, app->signal_info.info4); y += lineheight; + + /* End transmission. Here state is guaranteed + * to be SendSignalEndTransmission */ + return level_duration_reset(); +} + +/* Vibrate and produce a click sound when a signal is sent. */ +void notify_signal_sent(ProtoViewApp *app) { + static const NotificationSequence sent_seq = { + &message_blue_255, + &message_vibro_on, + &message_note_g1, + &message_delay_10, + &message_sound_off, + &message_vibro_off, + &message_blue_0, + NULL + }; + notification_message(app->notification, &sent_seq); } /* Handle input for the info view. */ void process_input_info(ProtoViewApp *app, InputEvent input) { - if (input.type == InputTypeShort) { - if (input.key == InputKeyOk) { + /* If we don't have a decoded signal, we don't allow to go up/down + * in the subviews: they are only useful when a loaded signal. */ + if (app->signal_decoded && + ui_process_subview_updown(app,input,SubViewInfoLast)) return; + + InfoViewPrivData *privdata = app->view_privdata; + int subview = ui_get_current_subview(app); + + /* Main subview. */ + if (subview == SubViewInfoMain) { + if (input.type == InputTypeLong && input.key == InputKeyOk) { /* Reset the current sample to capture the next. */ reset_current_signal(app); + } else if (input.type == InputTypeShort && input.key == InputKeyOk) { + /* Show next info page. */ + privdata->cur_info_page++; + } + } else if (subview == SubViewInfoSave) { + /* Save subview. */ + if (input.type == InputTypePress && input.key == InputKeyRight) { + privdata->signal_display_start_row++; + } else if (input.type == InputTypePress && input.key == InputKeyLeft) { + if (privdata->signal_display_start_row != 0) + privdata->signal_display_start_row--; + } else if (input.type == InputTypeLong && input.key == InputKeyOk) + { + // We have have the buffer already allocated, in case the + // user aborted with BACK a previous saving. + if (privdata->filename == NULL) + privdata->filename = malloc(SAVE_FILENAME_LEN); + set_signal_random_filename(app,privdata->filename,SAVE_FILENAME_LEN); + ui_show_keyboard(app, privdata->filename, SAVE_FILENAME_LEN, + text_input_done_callback); + } else if (input.type == InputTypeShort && input.key == InputKeyOk) { + SendSignalCtx send_state; + send_signal_init(&send_state,app); + radio_tx_signal(app,radio_tx_feed_data,&send_state); + notify_signal_sent(app); } } } + +/* Called on view exit. */ +void view_exit_info(ProtoViewApp *app) { + InfoViewPrivData *privdata = app->view_privdata; + // When the user aborts the keyboard input, we are left with the + // filename buffer allocated. + if (privdata->filename) free(privdata->filename); +} diff --git a/applications/plugins/protoview/view_raw_signal.c b/applications/plugins/protoview/view_raw_signal.c index 58d23e8eeb..023e986f95 100644 --- a/applications/plugins/protoview/view_raw_signal.c +++ b/applications/plugins/protoview/view_raw_signal.c @@ -65,7 +65,7 @@ void render_view_raw_pulses(Canvas *const canvas, ProtoViewApp *app) { canvas_draw_str_with_border(canvas, 97, 63, buf, ColorWhite, ColorBlack); if (app->signal_decoded) { canvas_set_font(canvas, FontPrimary); - canvas_draw_str_with_border(canvas, 1, 61, app->signal_info.name, ColorWhite, ColorBlack); + canvas_draw_str_with_border(canvas, 1, 61, app->msg_info->decoder->name, ColorWhite, ColorBlack); } } @@ -77,14 +77,15 @@ void process_input_raw_pulses(ProtoViewApp *app, InputEvent input) { * previous samples. */ if (input.key == InputKeyRight) app->signal_offset++; else if (input.key == InputKeyLeft) app->signal_offset--; - else if (input.key == InputKeyOk) { - app->signal_offset = 0; - app->us_scale = PROTOVIEW_RAW_VIEW_DEFAULT_SCALE; - } - } else if (input.type == InputTypeShort) { + } else if (input.type == InputTypeLong) { if (input.key == InputKeyOk) { /* Reset the current sample to capture the next. */ reset_current_signal(app); + } + } else if (input.type == InputTypeShort) { + if (input.key == InputKeyOk) { + app->signal_offset = 0; + adjust_raw_view_scale(app,DetectedSamples->short_pulse_dur); } else if (input.key == InputKeyDown) { /* Rescaling. The set becomes finer under 50us per pixel. */ uint32_t scale_step = app->us_scale >= 50 ? 50 : 10; @@ -95,3 +96,19 @@ void process_input_raw_pulses(ProtoViewApp *app, InputEvent input) { } } } + +/* Adjust raw view scale depending on short pulse duration. */ +void adjust_raw_view_scale(ProtoViewApp *app, uint32_t short_pulse_dur) { + if (short_pulse_dur == 0) + app->us_scale = PROTOVIEW_RAW_VIEW_DEFAULT_SCALE; + else if (short_pulse_dur < 75) + app->us_scale = 10; + else if (short_pulse_dur < 145) + app->us_scale = 30; + else if (short_pulse_dur < 400) + app->us_scale = 100; + else if (short_pulse_dur < 1000) + app->us_scale = 200; + else + app->us_scale = PROTOVIEW_RAW_VIEW_DEFAULT_SCALE; +} diff --git a/applications/plugins/snake_game/snake_game.c b/applications/plugins/snake_game/snake_game.c index b2cf450117..2815e2f372 100644 --- a/applications/plugins/snake_game/snake_game.c +++ b/applications/plugins/snake_game/snake_game.c @@ -1,6 +1,3 @@ -#include "helpers/snake_file_handler.h" -#include "helpers/snake_types.h" - #include #include #include @@ -8,7 +5,52 @@ #include #include #include -#include + +typedef struct { + // +-----x + // | + // | + // y + uint8_t x; + uint8_t y; +} Point; + +typedef enum { + GameStateLife, + + // https://melmagazine.com/en-us/story/snake-nokia-6110-oral-history-taneli-armanto + // Armanto: While testing the early versions of the game, I noticed it was hard + // to control the snake upon getting close to and edge but not crashing — especially + // in the highest speed levels. I wanted the highest level to be as fast as I could + // possibly make the device "run," but on the other hand, I wanted to be friendly + // and help the player manage that level. Otherwise it might not be fun to play. So + // I implemented a little delay. A few milliseconds of extra time right before + // the player crashes, during which she can still change the directions. And if + // she does, the game continues. + GameStateLastChance, + + GameStateGameOver, +} GameState; + +// Note: do not change without purpose. Current values are used in smart +// orthogonality calculation in `snake_game_get_turn_snake`. +typedef enum { + DirectionUp, + DirectionRight, + DirectionDown, + DirectionLeft, +} Direction; + +#define MAX_SNAKE_LEN 253 + +typedef struct { + Point points[MAX_SNAKE_LEN]; + uint16_t len; + Direction currentMovement; + Direction nextMovement; // if backward of currentMovement, ignore + Point fruit; + GameState state; +} SnakeState; typedef enum { EventTypeTick, @@ -74,35 +116,22 @@ static void snake_game_render_callback(Canvas* const canvas, void* ctx) { canvas_draw_box(canvas, p.x, p.y, 4, 4); } - // Show score on the game field - if(snake_state->state != GameStateGameOver) { - char buffer2[6]; - canvas_set_font(canvas, FontBatteryPercent); - snprintf(buffer2, sizeof(buffer2), "%u", (snake_state->len - 7)); - canvas_draw_str_aligned(canvas, 124, 10, AlignRight, AlignBottom, buffer2); - } // Game Over banner if(snake_state->state == GameStateGameOver) { // Screen is 128x64 px canvas_set_color(canvas, ColorWhite); - canvas_draw_box(canvas, 32, 20, 64, 34); + canvas_draw_box(canvas, 34, 20, 62, 24); canvas_set_color(canvas, ColorBlack); - canvas_draw_frame(canvas, 32, 20, 64, 34); + canvas_draw_frame(canvas, 34, 20, 62, 24); canvas_set_font(canvas, FontPrimary); canvas_draw_str(canvas, 37, 31, "Game Over"); - char buffer[18]; canvas_set_font(canvas, FontSecondary); - snprintf(buffer, sizeof(buffer), "Score: %u", snake_state->len); + char buffer[12]; + snprintf(buffer, sizeof(buffer), "Score: %u", snake_state->len - 7U); canvas_draw_str_aligned(canvas, 64, 41, AlignCenter, AlignBottom, buffer); - - snprintf(buffer, sizeof(buffer), "Highscore: %d", snake_state->highscore); - canvas_draw_str_aligned(canvas, 64, 51, AlignCenter, AlignBottom, buffer); - } - if((snake_state->len - 7) % 20 == 0 && (snake_state->len - 7) != 0) { - DOLPHIN_DEED(getRandomDeed()); } release_mutex((ValueMutex*)ctx, snake_state); @@ -233,24 +262,16 @@ static void snake_game_move_snake(SnakeState* const snake_state, Point const nex snake_state->points[0] = next_step; } -static void snake_game_game_over(SnakeState* const snake_state, NotificationApp* notification) { - snake_state->state = GameStateGameOver; - snake_state->len = snake_state->len - 7; - if(snake_state->len > snake_state->highscore) { - snake_state->isNewHighscore = true; - snake_state->highscore = snake_state->len; - } - - notification_message_block(notification, &sequence_fail); -} - static void snake_game_process_game_step(SnakeState* const snake_state, NotificationApp* notification) { if(snake_state->state == GameStateGameOver) { return; } - snake_state->currentMovement = snake_game_get_turn_snake(snake_state); + bool can_turn = (snake_state->points[0].x % 2 == 0) && (snake_state->points[0].y % 2 == 0); + if(can_turn) { + snake_state->currentMovement = snake_game_get_turn_snake(snake_state); + } Point next_step = snake_game_get_next_step(snake_state); @@ -260,7 +281,8 @@ static void snake_state->state = GameStateLastChance; return; } else if(snake_state->state == GameStateLastChance) { - snake_game_game_over(snake_state, notification); + snake_state->state = GameStateGameOver; + notification_message_block(notification, &sequence_fail); return; } } else { @@ -271,7 +293,8 @@ static void crush = snake_game_collision_with_tail(snake_state, next_step); if(crush) { - snake_game_game_over(snake_state, notification); + snake_state->state = GameStateGameOver; + notification_message_block(notification, &sequence_fail); return; } @@ -279,7 +302,8 @@ static void if(eatFruit) { snake_state->len++; if(snake_state->len >= MAX_SNAKE_LEN) { - snake_game_game_over(snake_state, notification); + snake_state->state = GameStateGameOver; + notification_message_block(notification, &sequence_fail); return; } } @@ -298,16 +322,11 @@ int32_t snake_game_app(void* p) { FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(SnakeEvent)); SnakeState* snake_state = malloc(sizeof(SnakeState)); - snake_state->isNewHighscore = false; - snake_state->highscore = 0; - if(!snake_game_init_game_from_file(snake_state)) { - snake_game_init_game(snake_state); - } + snake_game_init_game(snake_state); ValueMutex state_mutex; if(!init_mutex(&state_mutex, snake_state, sizeof(SnakeState))) { FURI_LOG_E("SnakeGame", "cannot create mutex\r\n"); - furi_message_queue_free(event_queue); free(snake_state); return 255; } @@ -358,9 +377,6 @@ int32_t snake_game_app(void* p) { } break; case InputKeyBack: - if(snake_state->state == GameStateLife) { - snake_game_save_game_to_file(snake_state); - } processing = false; break; default: @@ -378,11 +394,8 @@ int32_t snake_game_app(void* p) { release_mutex(&state_mutex, snake_state); } - if(snake_state->isNewHighscore) { - snake_game_save_score_to_file(snake_state->highscore); - } - // Wait for all notifications to be played and return backlight to normal state - notification_message_block(notification, &sequence_display_backlight_enforce_auto); + // Return backlight to normal state + notification_message(notification, &sequence_display_backlight_enforce_auto); furi_timer_free(timer); view_port_enabled_set(view_port, false); @@ -396,3 +409,26 @@ int32_t snake_game_app(void* p) { return 0; } + +// Screen is 128x64 px +// (4 + 4) * 16 - 4 + 2 + 2border == 128 +// (4 + 4) * 8 - 4 + 2 + 2border == 64 +// Game field from point{x: 0, y: 0} to point{x: 30, y: 14}. +// The snake turns only in even cells - intersections. +// ┌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┐ +// ╎ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ╎ +// ╎ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ╎ +// ╎ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ╎ +// ╎ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ╎ +// ╎ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ╎ +// ╎ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ╎ +// ╎ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ╎ +// ╎ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ╎ +// ╎ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ╎ +// ╎ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ╎ +// ╎ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ╎ +// ╎ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ╎ +// ╎ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ╎ +// ╎ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ╎ +// ╎ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪ ╎ +// └╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┘ diff --git a/applications/plugins/tama_p1/README.md b/applications/plugins/tama_p1/README.md index 20690c7a28..0c06eb7122 100644 --- a/applications/plugins/tama_p1/README.md +++ b/applications/plugins/tama_p1/README.md @@ -3,15 +3,29 @@ Tama P1 Emulator for Flipper Zero This is a tama P1 Emulator app for Flipper Zero, based on [TamaLIB](https://github.com/jcrona/tamalib/). +![Alt Text](tama.gif) + How to play ----------- Create a `tama_p1` folder in your microSD card, and put the ROM as `rom.bin`. -Left button is A, OK is B, and right button is C. Hold the back button to exit. -There is currently no saving, so your progress will be reset when you exit the -app. +Use a search engine to find the Tamagotchi ROM. There is a file named `a`. +Rename this to `rom.bin`. + +- Left button is A. +- OK is B. +- Right button is C. +- Holding the Up button functions the same as press both A and C, which mutes the volume. +- Hold the Back button to save and exit. + Building -------- +Move this folder into flippers applications/plugins/tama_p1. + + +Launching the app, directly from console to flipper: +`./fbt launch_app APPSRC=applications\plugins\tama_p1` + Run the following to compile icons: ``` scripts/assets.py icons applications/tama_p1/icons applications/tama_p1/compiled @@ -20,16 +34,26 @@ scripts/assets.py icons applications/tama_p1/icons applications/tama_p1/compiled Note: you may also need to add `-Wno-unused-parameter` to `CCFLAGS` in `site_cons/cc.scons` to suppress unused parameter errors in TamaLIB. +Debugging +--------- +Using the serial script from [FlipperScripts](https://github.com/DroomOne/FlipperScripts/blob/main/serial_logger.py) +it is easy to add direct logging after running the application: +`python .\serial_logger.py` + +`./fbt launch_app APPSRC=applications\plugins\tama_p1; python .\serial_logger.py` + + Implemented ----------- - Basic emulation - Input - Sound +- Saving/Loading emulator state (stored in `/ext/tama_p1/save.bin`) +- Mute button combo shortcut (Up = A+C) To-do ----- -- Saving/loading - - Multiple slots? +- more than one save slot - In-game reset - Test mode? - Volume adjustment diff --git a/applications/plugins/tama_p1/hal.c b/applications/plugins/tama_p1/hal.c index 7c07c5252f..211457803a 100644 --- a/applications/plugins/tama_p1/hal.c +++ b/applications/plugins/tama_p1/hal.c @@ -36,11 +36,11 @@ static bool_t tama_p1_hal_is_log_enabled(log_level_t level) { static void tama_p1_hal_log(log_level_t level, char* buff, ...) { if(!tama_p1_hal_is_log_enabled(level)) return; - FuriString* string = NULL; + FuriString* string = furi_string_alloc(); va_list args; va_start(args, buff); furi_string_cat_vprintf(string, buff, args); - va_end(args); + va_end(args); switch(level) { case LOG_ERROR: @@ -50,7 +50,10 @@ static void tama_p1_hal_log(log_level_t level, char* buff, ...) { FURI_LOG_I(TAG_HAL, "%s", furi_string_get_cstr(string)); break; case LOG_MEMORY: + break; case LOG_CPU: + FURI_LOG_D(TAG_HAL, "%s", furi_string_get_cstr(string)); + break; default: FURI_LOG_D(TAG_HAL, "%s", furi_string_get_cstr(string)); break; diff --git a/applications/plugins/tama_p1/tama.gif b/applications/plugins/tama_p1/tama.gif new file mode 100644 index 0000000000..c412222609 Binary files /dev/null and b/applications/plugins/tama_p1/tama.gif differ diff --git a/applications/plugins/tama_p1/tama.h b/applications/plugins/tama_p1/tama.h index d3b67b90d6..e2a2674432 100644 --- a/applications/plugins/tama_p1/tama.h +++ b/applications/plugins/tama_p1/tama.h @@ -9,6 +9,11 @@ #define TAMA_LCD_ICON_SIZE 14 #define TAMA_LCD_ICON_MARGIN 1 +#define STATE_FILE_MAGIC "TLST" +#define STATE_FILE_VERSION 2 +#define TAMA_SAVE_PATH EXT_PATH("tama_p1/save.bin") + + typedef struct { FuriThread* thread; hal_t hal; diff --git a/applications/plugins/tama_p1/tama_p1.c b/applications/plugins/tama_p1/tama_p1.c index 6e79720002..7184638d76 100644 --- a/applications/plugins/tama_p1/tama_p1.c +++ b/applications/plugins/tama_p1/tama_p1.c @@ -41,8 +41,10 @@ static void tama_p1_draw_callback(Canvas* const canvas, void* cb_ctx) { uint16_t canv_height = canvas_height(canvas); uint16_t lcd_matrix_scaled_width = 32 * TAMA_SCREEN_SCALE_FACTOR; uint16_t lcd_matrix_scaled_height = 16 * TAMA_SCREEN_SCALE_FACTOR; + // uint16_t lcd_matrix_top = 0; uint16_t lcd_matrix_top = (canv_height - lcd_matrix_scaled_height) / 2; uint16_t lcd_matrix_left = (canv_width - lcd_matrix_scaled_width) / 2; + uint16_t lcd_icon_upper_top = lcd_matrix_top - TAMA_LCD_ICON_SIZE - TAMA_LCD_ICON_MARGIN; uint16_t lcd_icon_upper_left = lcd_matrix_left; uint16_t lcd_icon_lower_top = @@ -50,14 +52,7 @@ static void tama_p1_draw_callback(Canvas* const canvas, void* cb_ctx) { uint16_t lcd_icon_lower_left = lcd_matrix_left; uint16_t lcd_icon_spacing_horiz = (lcd_matrix_scaled_width - (4 * TAMA_LCD_ICON_SIZE)) / 3 + TAMA_LCD_ICON_SIZE; - - // Draw pixels - // canvas_draw_frame( - // canvas, - // lcd_matrix_left, - // lcd_matrix_top, - // lcd_matrix_scaled_width, - // lcd_matrix_scaled_height); + uint16_t y = lcd_matrix_top; for(uint8_t row = 0; row < 16; ++row) { @@ -74,21 +69,23 @@ static void tama_p1_draw_callback(Canvas* const canvas, void* cb_ctx) { y += TAMA_SCREEN_SCALE_FACTOR; } - // Draw icons + // Start drawing icons uint8_t lcd_icons = g_ctx->icons; - // Top + + // Draw top icons y = lcd_icon_upper_top; + // y = 64 - TAMA_LCD_ICON_SIZE; uint16_t x_ic = lcd_icon_upper_left; for(uint8_t i = 0; i < 4; ++i) { - // canvas_draw_frame(canvas, x_ic, y, TAMA_LCD_ICON_SIZE, TAMA_LCD_ICON_SIZE); if(lcd_icons & 1) { canvas_draw_icon(canvas, x_ic, y, icons_list[i]); } + // x_ic += TAMA_LCD_ICON_SIZE + 4; x_ic += lcd_icon_spacing_horiz; lcd_icons >>= 1; } - // Bottom + // Draw bottom icons y = lcd_icon_lower_top; x_ic = lcd_icon_lower_left; for(uint8_t i = 4; i < 8; ++i) { @@ -117,6 +114,225 @@ static void tama_p1_update_timer_callback(FuriMessageQueue* event_queue) { TamaEvent event = {.type = EventTypeTick}; furi_message_queue_put(event_queue, &event, 0); } + +static void tama_p1_load_state() { + state_t *state; + uint8_t buf[4]; + bool error = false; + state = tamalib_get_state(); + + Storage* storage = furi_record_open(RECORD_STORAGE); + File* file = storage_file_alloc(storage); + if(storage_file_open(file, TAMA_SAVE_PATH, FSAM_READ, FSOM_OPEN_EXISTING)) { + + storage_file_read(file, &buf, 4); + if (buf[0] != (uint8_t) STATE_FILE_MAGIC[0] || buf[1] != (uint8_t) STATE_FILE_MAGIC[1] || + buf[2] != (uint8_t) STATE_FILE_MAGIC[2] || buf[3] != (uint8_t) STATE_FILE_MAGIC[3]) { + FURI_LOG_E(TAG, "FATAL: Wrong state file magic in \"%s\" !\n", TAMA_SAVE_PATH); + error = true; + } + + storage_file_read(file, &buf, 1); + if (buf[0] != STATE_FILE_VERSION) { + FURI_LOG_E(TAG, "FATAL: Unsupported version"); + error = true; + } + if (!error) { + FURI_LOG_D(TAG, "Reading save.bin"); + + storage_file_read(file, &buf, 2); + *(state->pc) = buf[0] | ((buf[1] & 0x1F) << 8); + + storage_file_read(file, &buf, 2); + *(state->x) = buf[0] | ((buf[1] & 0xF) << 8); + + storage_file_read(file, &buf, 2); + *(state->y) = buf[0] | ((buf[1] & 0xF) << 8); + + storage_file_read(file, &buf, 1); + *(state->a) = buf[0] & 0xF; + + storage_file_read(file, &buf, 1); + *(state->b) = buf[0] & 0xF; + + storage_file_read(file, &buf, 1); + *(state->np) = buf[0] & 0x1F; + + storage_file_read(file, &buf, 1); + *(state->sp) = buf[0]; + + storage_file_read(file, &buf, 1); + *(state->flags) = buf[0] & 0xF; + + storage_file_read(file, &buf, 4); + *(state->tick_counter) = buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24); + + storage_file_read(file, &buf, 4); + *(state->clk_timer_timestamp) = buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24); + + storage_file_read(file, &buf, 4); + *(state->prog_timer_timestamp) = buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24); + + storage_file_read(file, &buf, 1); + *(state->prog_timer_enabled) = buf[0] & 0x1; + + storage_file_read(file, &buf, 1); + *(state->prog_timer_data) = buf[0]; + + storage_file_read(file, &buf, 1); + *(state->prog_timer_rld) = buf[0]; + + storage_file_read(file, &buf, 4); + *(state->call_depth) = buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24); + + FURI_LOG_D(TAG, "Restoring Interupts"); + for (uint32_t i = 0; i < INT_SLOT_NUM; i++) { + storage_file_read(file, &buf, 1); + state->interrupts[i].factor_flag_reg = buf[0] & 0xF; + + storage_file_read(file, &buf, 1); + state->interrupts[i].mask_reg = buf[0] & 0xF; + + storage_file_read(file, &buf, 1); + state->interrupts[i].triggered = buf[0] & 0x1; + } + + /* First 640 half bytes correspond to the RAM */ + FURI_LOG_D(TAG, "Restoring RAM"); + for (uint32_t i = 0; i < MEM_RAM_SIZE; i++) { + storage_file_read(file, &buf, 1); + SET_RAM_MEMORY(state->memory, i + MEM_RAM_ADDR, buf[0] & 0xF); + } + + /* I/Os are from 0xF00 to 0xF7F */ + FURI_LOG_D(TAG, "Restoring I/O"); + for (uint32_t i = 0; i < MEM_IO_SIZE; i++) { + storage_file_read(file, &buf, 1); + SET_IO_MEMORY(state->memory, i + MEM_IO_ADDR, buf[0] & 0xF); + } + FURI_LOG_D(TAG, "Refreshing Hardware"); + tamalib_refresh_hw(); + } + } + + storage_file_close(file); + storage_file_free(file); + furi_record_close(RECORD_STORAGE); +} + + +static void tama_p1_save_state() { + + // Saving state + FURI_LOG_D(TAG, "Saving Gamestate"); + uint8_t buf[4]; + state_t *state; + uint32_t offset = 0; + state = tamalib_get_state(); + + Storage* storage = furi_record_open(RECORD_STORAGE); + File* file = storage_file_alloc(storage); + + if(storage_file_open(file, TAMA_SAVE_PATH, FSAM_WRITE, FSOM_CREATE_ALWAYS)) { + buf[0] = (uint8_t) STATE_FILE_MAGIC[0]; + buf[1] = (uint8_t) STATE_FILE_MAGIC[1]; + buf[2] = (uint8_t) STATE_FILE_MAGIC[2]; + buf[3] = (uint8_t) STATE_FILE_MAGIC[3]; + offset += storage_file_write(file, &buf, sizeof(buf)); + + buf[0] = STATE_FILE_VERSION & 0xFF; + offset += storage_file_write(file, &buf, 1); + + buf[0] = *(state->pc) & 0xFF; + buf[1] = (*(state->pc) >> 8) & 0x1F; + offset += storage_file_write(file, &buf, 2); + + buf[0] = *(state->x) & 0xFF; + buf[1] = (*(state->x) >> 8) & 0xF; + offset += storage_file_write(file, &buf, 2); + + buf[0] = *(state->y) & 0xFF; + buf[1] = (*(state->y) >> 8) & 0xF; + offset += storage_file_write(file, &buf, 2); + + buf[0] = *(state->a) & 0xF; + offset += storage_file_write(file, &buf, 1); + + buf[0] = *(state->b) & 0xF; + offset += storage_file_write(file, &buf, 1); + + buf[0] = *(state->np) & 0x1F; + offset += storage_file_write(file, &buf, 1); + + buf[0] = *(state->sp) & 0xFF; + offset += storage_file_write(file, &buf, 1); + + buf[0] = *(state->flags) & 0xF; + offset += storage_file_write(file, &buf, 1); + + buf[0] = *(state->tick_counter) & 0xFF; + buf[1] = (*(state->tick_counter) >> 8) & 0xFF; + buf[2] = (*(state->tick_counter) >> 16) & 0xFF; + buf[3] = (*(state->tick_counter) >> 24) & 0xFF; + offset += storage_file_write(file, &buf, sizeof(buf)); + + buf[0] = *(state->clk_timer_timestamp) & 0xFF; + buf[1] = (*(state->clk_timer_timestamp) >> 8) & 0xFF; + buf[2] = (*(state->clk_timer_timestamp) >> 16) & 0xFF; + buf[3] = (*(state->clk_timer_timestamp) >> 24) & 0xFF; + offset += storage_file_write(file, &buf, sizeof(buf)); + + buf[0] = *(state->prog_timer_timestamp) & 0xFF; + buf[1] = (*(state->prog_timer_timestamp) >> 8) & 0xFF; + buf[2] = (*(state->prog_timer_timestamp) >> 16) & 0xFF; + buf[3] = (*(state->prog_timer_timestamp) >> 24) & 0xFF; + offset += storage_file_write(file, &buf, sizeof(buf)); + + buf[0] = *(state->prog_timer_enabled) & 0x1; + offset += storage_file_write(file, &buf, 1); + + buf[0] = *(state->prog_timer_data) & 0xFF; + offset += storage_file_write(file, &buf, 1); + + buf[0] = *(state->prog_timer_rld) & 0xFF; + offset += storage_file_write(file, &buf, 1); + + buf[0] = *(state->call_depth) & 0xFF; + buf[1] = (*(state->call_depth) >> 8) & 0xFF; + buf[2] = (*(state->call_depth) >> 16) & 0xFF; + buf[3] = (*(state->call_depth) >> 24) & 0xFF; + offset += storage_file_write(file, &buf, sizeof(buf)); + + for (uint32_t i = 0; i < INT_SLOT_NUM; i++) { + buf[0] = state->interrupts[i].factor_flag_reg & 0xF; + offset += storage_file_write(file, &buf, 1); + + buf[0] = state->interrupts[i].mask_reg & 0xF; + offset += storage_file_write(file, &buf, 1); + + buf[0] = state->interrupts[i].triggered & 0x1; + offset += storage_file_write(file, &buf, 1); + } + + /* First 640 half bytes correspond to the RAM */ + for (uint32_t i = 0; i < MEM_RAM_SIZE; i++) { + buf[0] = GET_RAM_MEMORY(state->memory, i + MEM_RAM_ADDR) & 0xF; + offset += storage_file_write(file, &buf, 1); + } + + /* I/Os are from 0xF00 to 0xF7F */ + for (uint32_t i = 0; i < MEM_IO_SIZE; i++) { + buf[0] = GET_IO_MEMORY(state->memory, i + MEM_IO_ADDR) & 0xF; + offset += storage_file_write(file, &buf, 1); + } + } + storage_file_close(file); + storage_file_free(file); + furi_record_close(RECORD_STORAGE); + + FURI_LOG_D(TAG, "Finished Writing %lu", offset); +} + static int32_t tama_p1_worker(void* context) { bool running = true; @@ -125,6 +341,9 @@ static int32_t tama_p1_worker(void* context) { cpu_sync_ref_timestamp(); LL_TIM_EnableCounter(TIM2); + + tama_p1_load_state(); + while(running) { if(furi_thread_flags_get()) { running = false; @@ -138,6 +357,8 @@ static int32_t tama_p1_worker(void* context) { furi_mutex_release(mutex); return 0; } + + static void tama_p1_init(TamaApp* const ctx) { g_ctx = ctx; @@ -264,12 +485,22 @@ int32_t tama_p1_app(void* p) { tamalib_set_button(BTN_MIDDLE, tama_btn_state); } else if(event.input.key == InputKeyRight) { tamalib_set_button(BTN_RIGHT, tama_btn_state); + } else if(event.input.key == InputKeyDown && event.input.type == InputTypeShort) { + // TODO: pause or fast-forward tamagotchi + tama_p1_save_state(); + } else if(event.input.key == InputKeyUp) { // mute tamagotchi + tamalib_set_button(BTN_LEFT, tama_btn_state); + tamalib_set_button(BTN_RIGHT, tama_btn_state); + } else if(event.input.key == InputKeyBack && event.input.type == InputTypeShort) { + tama_p1_save_state(); } } if(event.input.key == InputKeyBack && event.input.type == InputTypeLong) { furi_timer_stop(timer); running = false; + + tama_p1_save_state(); } } diff --git a/applications/plugins/totp/LICENSE b/applications/plugins/totp/LICENSE deleted file mode 100644 index 65504e7b1b..0000000000 --- a/applications/plugins/totp/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2022 Alexander Kopachov - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/applications/plugins/totp/cli/commands/add/add.c b/applications/plugins/totp/cli/commands/add/add.c index ba36a973ab..2183d52777 100644 --- a/applications/plugins/totp/cli/commands/add/add.c +++ b/applications/plugins/totp/cli/commands/add/add.c @@ -14,6 +14,8 @@ #define TOTP_CLI_COMMAND_ADD_ARG_DIGITS "digits" #define TOTP_CLI_COMMAND_ADD_ARG_DIGITS_PREFIX "-d" #define TOTP_CLI_COMMAND_ADD_ARG_UNSECURE_PREFIX "-u" +#define TOTP_CLI_COMMAND_ADD_ARG_DURATION "duration" +#define TOTP_CLI_COMMAND_ADD_ARG_DURATION_PREFIX "-l" static bool token_info_set_algo_from_str(TokenInfo* token_info, const FuriString* str) { if(furi_string_cmpi_str(str, TOTP_CONFIG_TOKEN_ALGO_SHA1_NAME) == 0) { @@ -34,6 +36,16 @@ static bool token_info_set_algo_from_str(TokenInfo* token_info, const FuriString return false; } +static bool args_read_uint8_and_trim(FuriString* args, uint8_t* value) { + int int_value; + if(!args_read_int_and_trim(args, &int_value) || int_value < 0 || int_value > UINT8_MAX) { + return false; + } + + *value = (uint8_t)int_value; + return true; +} + void totp_cli_command_add_docopt_commands() { TOTP_CLI_PRINTF(" " TOTP_CLI_COMMAND_ADD ", " TOTP_CLI_COMMAND_ADD_ALT ", " TOTP_CLI_COMMAND_ADD_ALT2 " Add new token\r\n"); @@ -42,11 +54,11 @@ void totp_cli_command_add_docopt_commands() { void totp_cli_command_add_docopt_usage() { TOTP_CLI_PRINTF( " " TOTP_CLI_COMMAND_NAME - " " DOCOPT_REQUIRED(TOTP_CLI_COMMAND_ADD " | " TOTP_CLI_COMMAND_ADD_ALT " | " TOTP_CLI_COMMAND_ADD_ALT2) " " DOCOPT_ARGUMENT(TOTP_CLI_COMMAND_ADD_ARG_NAME) " " DOCOPT_OPTIONAL( + " " DOCOPT_REQUIRED(TOTP_CLI_COMMAND_ADD " | " TOTP_CLI_COMMAND_ADD_ALT " | " TOTP_CLI_COMMAND_ADD_ALT2) " " DOCOPT_ARGUMENT(TOTP_CLI_COMMAND_ADD_ARG_NAME) " " DOCOPT_OPTIONAL(DOCOPT_OPTION(TOTP_CLI_COMMAND_ADD_ARG_ALGO_PREFIX, DOCOPT_ARGUMENT(TOTP_CLI_COMMAND_ADD_ARG_ALGO))) " " DOCOPT_OPTIONAL( DOCOPT_OPTION( - TOTP_CLI_COMMAND_ADD_ARG_ALGO_PREFIX, + TOTP_CLI_COMMAND_ADD_ARG_DIGITS_PREFIX, DOCOPT_ARGUMENT( - TOTP_CLI_COMMAND_ADD_ARG_ALGO))) " " DOCOPT_OPTIONAL(DOCOPT_OPTION(TOTP_CLI_COMMAND_ADD_ARG_DIGITS_PREFIX, DOCOPT_ARGUMENT(TOTP_CLI_COMMAND_ADD_ARG_DIGITS))) " " DOCOPT_OPTIONAL(DOCOPT_SWITCH(TOTP_CLI_COMMAND_ADD_ARG_UNSECURE_PREFIX)) "\r\n"); + TOTP_CLI_COMMAND_ADD_ARG_DIGITS))) " " DOCOPT_OPTIONAL(DOCOPT_OPTION(TOTP_CLI_COMMAND_ADD_ARG_DURATION_PREFIX, DOCOPT_ARGUMENT(TOTP_CLI_COMMAND_ADD_ARG_DURATION))) " " DOCOPT_OPTIONAL(DOCOPT_SWITCH(TOTP_CLI_COMMAND_ADD_ARG_UNSECURE_PREFIX)) "\r\n"); } void totp_cli_command_add_docopt_arguments() { @@ -64,6 +76,10 @@ void totp_cli_command_add_docopt_options() { TOTP_CLI_COMMAND_ADD_ARG_DIGITS_PREFIX, DOCOPT_ARGUMENT( TOTP_CLI_COMMAND_ADD_ARG_DIGITS)) " Number of digits to generate, one of: 6, 8 " DOCOPT_DEFAULT("6") "\r\n"); + TOTP_CLI_PRINTF(" " DOCOPT_OPTION( + TOTP_CLI_COMMAND_ADD_ARG_DURATION_PREFIX, + DOCOPT_ARGUMENT( + TOTP_CLI_COMMAND_ADD_ARG_DURATION)) " Token lifetime duration in seconds, between: 15 and 255 " DOCOPT_DEFAULT("30") "\r\n"); TOTP_CLI_PRINTF(" " DOCOPT_SWITCH( TOTP_CLI_COMMAND_ADD_ARG_UNSECURE_PREFIX) " Show console user input as-is without masking\r\n"); } @@ -110,16 +126,32 @@ void totp_cli_command_add_handle(PluginState* plugin_state, FuriString* args, Cl parsed = true; } } else if(furi_string_cmpi_str(temp_str, TOTP_CLI_COMMAND_ADD_ARG_DIGITS_PREFIX) == 0) { - if(!args_read_string_and_trim(args, temp_str)) { + uint8_t digit_value; + if(!args_read_uint8_and_trim(args, &digit_value)) { TOTP_CLI_PRINTF( - "Missed value for argument \"" TOTP_CLI_COMMAND_ADD_ARG_DIGITS_PREFIX + "Missed or incorrect value for argument \"" TOTP_CLI_COMMAND_ADD_ARG_DIGITS_PREFIX "\"\r\n"); - } else if(!token_info_set_digits_from_int( - token_info, CONVERT_CHAR_TO_DIGIT(furi_string_get_char(temp_str, 0)))) { + } else if(!token_info_set_digits_from_int(token_info, digit_value)) { TOTP_CLI_PRINTF( - "\"%s\" is incorrect value for argument \"" TOTP_CLI_COMMAND_ADD_ARG_DIGITS_PREFIX + "\"%" PRIu8 + "\" is incorrect value for argument \"" TOTP_CLI_COMMAND_ADD_ARG_DIGITS_PREFIX "\"\r\n", - furi_string_get_cstr(temp_str)); + digit_value); + } else { + parsed = true; + } + } else if(furi_string_cmpi_str(temp_str, TOTP_CLI_COMMAND_ADD_ARG_DURATION_PREFIX) == 0) { + uint8_t duration_value; + if(!args_read_uint8_and_trim(args, &duration_value)) { + TOTP_CLI_PRINTF( + "Missed or incorrect value for argument \"" TOTP_CLI_COMMAND_ADD_ARG_DURATION_PREFIX + "\"\r\n"); + } else if(!token_info_set_duration_from_int(token_info, duration_value)) { + TOTP_CLI_PRINTF( + "\"%" PRIu8 + "\" is incorrect value for argument \"" TOTP_CLI_COMMAND_ADD_ARG_DURATION_PREFIX + "\"\r\n", + duration_value); } else { parsed = true; } diff --git a/applications/plugins/totp/cli/commands/list/list.c b/applications/plugins/totp/cli/commands/list/list.c index 739a0de409..8ed9a136d2 100644 --- a/applications/plugins/totp/cli/commands/list/list.c +++ b/applications/plugins/totp/cli/commands/list/list.c @@ -40,19 +40,21 @@ void totp_cli_command_list_handle(PluginState* plugin_state, Cli* cli) { return; } - TOTP_CLI_PRINTF("+-----+-----------------------------+--------+--------+\r\n"); - TOTP_CLI_PRINTF("| %-*s | %-*s | %-*s | %-s |\r\n", 3, "#", 27, "Name", 6, "Algo", "Digits"); - TOTP_CLI_PRINTF("+-----+-----------------------------+--------+--------+\r\n"); + TOTP_CLI_PRINTF("+-----+---------------------------+--------+----+-----+\r\n"); + TOTP_CLI_PRINTF( + "| %-*s | %-*s | %-*s | %-s | %-s |\r\n", 3, "#", 25, "Name", 6, "Algo", "Ln", "Dur"); + TOTP_CLI_PRINTF("+-----+---------------------------+--------+----+-----+\r\n"); uint16_t index = 1; TOTP_LIST_FOREACH(plugin_state->tokens_list, node, { TokenInfo* token_info = (TokenInfo*)node->data; TOTP_CLI_PRINTF( - "| %-3" PRIu16 " | %-27.27s | %-6s | %-6" PRIu8 " |\r\n", + "| %-3" PRIu16 " | %-25.25s | %-6s | %-2" PRIu8 " | %-3" PRIu8 " |\r\n", index, token_info->name, get_algo_as_cstr(token_info->algo), - token_info->digits); + token_info->digits, + token_info->duration); index++; }); - TOTP_CLI_PRINTF("+-----+-----------------------------+--------+--------+\r\n"); + TOTP_CLI_PRINTF("+-----+---------------------------+--------+----+-----+\r\n"); } \ No newline at end of file diff --git a/applications/plugins/totp/services/config/config.c b/applications/plugins/totp/services/config/config.c index 4b2090d55c..cd19d19d40 100644 --- a/applications/plugins/totp/services/config/config.c +++ b/applications/plugins/totp/services/config/config.c @@ -5,6 +5,7 @@ #include "../../types/common.h" #include "../../types/token_info.h" #include "migrations/config_migration_v1_to_v2.h" +#include "migrations/config_migration_v2_to_v3.h" #define CONFIG_FILE_DIRECTORY_PATH EXT_PATH("apps_data/authenticator") #define CONFIG_FILE_PATH CONFIG_FILE_DIRECTORY_PATH "/totp.conf" @@ -173,6 +174,13 @@ static TotpConfigFileOpenResult totp_open_config_file(Storage* storage, FlipperF flipper_format_write_comment(fff_data_file, temp_str); flipper_format_write_comment_cstr(fff_data_file, " "); + flipper_format_write_comment_cstr( + fff_data_file, + "# Token lifetime duration in seconds. Should be between 15 and 255. Majority websites requires 30, however some rare websites may require custom lifetime. If you are not sure which one to use - use 30"); + furi_string_printf(temp_str, "%s: 30", TOTP_CONFIG_KEY_TOKEN_DURATION); + flipper_format_write_comment(fff_data_file, temp_str); + flipper_format_write_comment_cstr(fff_data_file, " "); + flipper_format_write_comment_cstr(fff_data_file, "=== TOKEN SAMPLE END ==="); flipper_format_write_comment_cstr(fff_data_file, " "); @@ -232,6 +240,12 @@ TotpConfigFileUpdateResult break; } + tmp_uint32 = token_info->duration; + if(!flipper_format_write_uint32(file, TOTP_CONFIG_KEY_TOKEN_DURATION, &tmp_uint32, 1)) { + update_result = TotpConfigFileUpdateError; + break; + } + update_result = TotpConfigFileUpdateSuccess; } while(false); @@ -483,6 +497,7 @@ TotpConfigFileOpenResult totp_config_file_load_base(PluginState* const plugin_st if(file_version == 1) { if(totp_config_migrate_v1_to_v2(fff_data_file, fff_backup_data_file)) { FURI_LOG_I(LOGGING_TAG, "Applied migration from v1 to v2"); + file_version = 2; } else { FURI_LOG_W( LOGGING_TAG, "An error occurred during migration from v1 to v2"); @@ -491,6 +506,18 @@ TotpConfigFileOpenResult totp_config_file_load_base(PluginState* const plugin_st } } + if(file_version == 2) { + if(totp_config_migrate_v2_to_v3(fff_data_file, fff_backup_data_file)) { + FURI_LOG_I(LOGGING_TAG, "Applied migration from v2 to v3"); + file_version = 3; + } else { + FURI_LOG_W( + LOGGING_TAG, "An error occurred during migration from v2 to v3"); + result = TotpConfigFileOpenError; + break; + } + } + flipper_format_file_close(fff_backup_data_file); flipper_format_free(fff_backup_data_file); flipper_format_rewind(fff_data_file); @@ -669,6 +696,12 @@ TokenLoadingResult totp_config_file_load_tokens(PluginState* const plugin_state) tokenInfo->digits = TOTP_6_DIGITS; } + if(!flipper_format_read_uint32( + fff_data_file, TOTP_CONFIG_KEY_TOKEN_DURATION, &temp_data32, 1) || + !token_info_set_duration_from_int(tokenInfo, temp_data32)) { + tokenInfo->duration = TOTP_TOKEN_DURATION_DEFAULT; + } + FURI_LOG_D(LOGGING_TAG, "Found token \"%s\"", tokenInfo->name); TOTP_LIST_INIT_OR_ADD(plugin_state->tokens_list, tokenInfo, furi_check); @@ -736,4 +769,4 @@ void totp_config_file_reset() { Storage* storage = totp_open_storage(); storage_simply_remove(storage, CONFIG_FILE_PATH); totp_close_storage(); -} +} \ No newline at end of file diff --git a/applications/plugins/totp/services/config/constants.h b/applications/plugins/totp/services/config/constants.h index 696ea15933..487fb159e1 100644 --- a/applications/plugins/totp/services/config/constants.h +++ b/applications/plugins/totp/services/config/constants.h @@ -1,13 +1,14 @@ #pragma once #define CONFIG_FILE_HEADER "Flipper TOTP plugin config file" -#define CONFIG_FILE_ACTUAL_VERSION 2 +#define CONFIG_FILE_ACTUAL_VERSION 3 #define TOTP_CONFIG_KEY_TIMEZONE "Timezone" #define TOTP_CONFIG_KEY_TOKEN_NAME "TokenName" #define TOTP_CONFIG_KEY_TOKEN_SECRET "TokenSecret" #define TOTP_CONFIG_KEY_TOKEN_ALGO "TokenAlgo" #define TOTP_CONFIG_KEY_TOKEN_DIGITS "TokenDigits" +#define TOTP_CONFIG_KEY_TOKEN_DURATION "TokenDuration" #define TOTP_CONFIG_KEY_CRYPTO_VERIFY "Crypto" #define TOTP_CONFIG_KEY_BASE_IV "BaseIV" #define TOTP_CONFIG_KEY_PINSET "PinIsSet" diff --git a/applications/plugins/totp/services/config/migrations/config_migration_v1_to_v2.c b/applications/plugins/totp/services/config/migrations/config_migration_v1_to_v2.c index 1ed8c37f00..c2ca8f9053 100644 --- a/applications/plugins/totp/services/config/migrations/config_migration_v1_to_v2.c +++ b/applications/plugins/totp/services/config/migrations/config_migration_v1_to_v2.c @@ -1,6 +1,7 @@ #include "config_migration_v1_to_v2.h" #include #include "../constants.h" +#include "../../../types/token_info.h" #define NEW_VERSION 2 @@ -36,7 +37,7 @@ bool totp_config_migrate_v1_to_v2( flipper_format_write_string_cstr( fff_data_file, TOTP_CONFIG_KEY_TOKEN_ALGO, TOTP_CONFIG_TOKEN_ALGO_SHA1_NAME); - uint32_t default_digits = 6; + const uint32_t default_digits = TOTP_6_DIGITS; flipper_format_write_uint32( fff_data_file, TOTP_CONFIG_KEY_TOKEN_DIGITS, &default_digits, 1); } diff --git a/applications/plugins/totp/services/config/migrations/config_migration_v2_to_v3.c b/applications/plugins/totp/services/config/migrations/config_migration_v2_to_v3.c new file mode 100644 index 0000000000..995b3b02e2 --- /dev/null +++ b/applications/plugins/totp/services/config/migrations/config_migration_v2_to_v3.c @@ -0,0 +1,70 @@ +#include "config_migration_v2_to_v3.h" +#include +#include "../constants.h" +#include "../../../types/token_info.h" + +#define NEW_VERSION 3 + +bool totp_config_migrate_v2_to_v3( + FlipperFormat* fff_data_file, + FlipperFormat* fff_backup_data_file) { + flipper_format_write_header_cstr(fff_data_file, CONFIG_FILE_HEADER, NEW_VERSION); + + FuriString* temp_str = furi_string_alloc(); + + if(flipper_format_read_string(fff_backup_data_file, TOTP_CONFIG_KEY_BASE_IV, temp_str)) { + flipper_format_write_string(fff_data_file, TOTP_CONFIG_KEY_BASE_IV, temp_str); + } + + flipper_format_rewind(fff_backup_data_file); + + if(flipper_format_read_string(fff_backup_data_file, TOTP_CONFIG_KEY_CRYPTO_VERIFY, temp_str)) { + flipper_format_write_string(fff_data_file, TOTP_CONFIG_KEY_CRYPTO_VERIFY, temp_str); + } + + flipper_format_rewind(fff_backup_data_file); + + if(flipper_format_read_string(fff_backup_data_file, TOTP_CONFIG_KEY_TIMEZONE, temp_str)) { + flipper_format_write_string(fff_data_file, TOTP_CONFIG_KEY_TIMEZONE, temp_str); + } + + flipper_format_rewind(fff_backup_data_file); + + if(flipper_format_read_string(fff_backup_data_file, TOTP_CONFIG_KEY_PINSET, temp_str)) { + flipper_format_write_string(fff_data_file, TOTP_CONFIG_KEY_PINSET, temp_str); + } + + flipper_format_rewind(fff_backup_data_file); + + if(flipper_format_read_string( + fff_backup_data_file, TOTP_CONFIG_KEY_NOTIFICATION_METHOD, temp_str)) { + flipper_format_write_string(fff_data_file, TOTP_CONFIG_KEY_NOTIFICATION_METHOD, temp_str); + } + + flipper_format_rewind(fff_backup_data_file); + + while(true) { + if(!flipper_format_read_string( + fff_backup_data_file, TOTP_CONFIG_KEY_TOKEN_NAME, temp_str)) { + break; + } + + flipper_format_write_string(fff_data_file, TOTP_CONFIG_KEY_TOKEN_NAME, temp_str); + + flipper_format_read_string(fff_backup_data_file, TOTP_CONFIG_KEY_TOKEN_SECRET, temp_str); + flipper_format_write_string(fff_data_file, TOTP_CONFIG_KEY_TOKEN_SECRET, temp_str); + + flipper_format_read_string(fff_backup_data_file, TOTP_CONFIG_KEY_TOKEN_ALGO, temp_str); + flipper_format_write_string(fff_data_file, TOTP_CONFIG_KEY_TOKEN_ALGO, temp_str); + + flipper_format_read_string(fff_backup_data_file, TOTP_CONFIG_KEY_TOKEN_DIGITS, temp_str); + flipper_format_write_string(fff_data_file, TOTP_CONFIG_KEY_TOKEN_DIGITS, temp_str); + + const uint32_t default_duration = TOTP_TOKEN_DURATION_DEFAULT; + flipper_format_write_uint32( + fff_data_file, TOTP_CONFIG_KEY_TOKEN_DURATION, &default_duration, 1); + } + + furi_string_free(temp_str); + return true; +} diff --git a/applications/plugins/totp/services/config/migrations/config_migration_v2_to_v3.h b/applications/plugins/totp/services/config/migrations/config_migration_v2_to_v3.h new file mode 100644 index 0000000000..e3078db14c --- /dev/null +++ b/applications/plugins/totp/services/config/migrations/config_migration_v2_to_v3.h @@ -0,0 +1,7 @@ +#pragma once + +#include + +bool totp_config_migrate_v2_to_v3( + FlipperFormat* fff_data_file, + FlipperFormat* fff_backup_data_file); diff --git a/applications/plugins/totp/types/token_info.c b/applications/plugins/totp/types/token_info.c index b432937887..60d04245f9 100644 --- a/applications/plugins/totp/types/token_info.c +++ b/applications/plugins/totp/types/token_info.c @@ -61,3 +61,12 @@ bool token_info_set_digits_from_int(TokenInfo* token_info, uint8_t digits) { return false; } + +bool token_info_set_duration_from_int(TokenInfo* token_info, uint8_t duration) { + if(duration >= 15) { + token_info->duration = duration; + return true; + } + + return false; +} \ No newline at end of file diff --git a/applications/plugins/totp/types/token_info.h b/applications/plugins/totp/types/token_info.h index 04caa68a81..d04564c421 100644 --- a/applications/plugins/totp/types/token_info.h +++ b/applications/plugins/totp/types/token_info.h @@ -2,6 +2,8 @@ #include +#define TOTP_TOKEN_DURATION_DEFAULT 30 + typedef uint8_t TokenHashAlgo; typedef uint8_t TokenDigitsCount; @@ -70,6 +72,11 @@ typedef struct { * @brief Desired TOTP token length */ TokenDigitsCount digits; + + /** + * @brief Desired TOTP token duration in seconds + */ + uint8_t duration; } TokenInfo; /** @@ -102,6 +109,14 @@ bool token_info_set_secret( * @brief Sets token digits count from \c uint8_t value * @param token_info instance whichs token digits count length should be updated * @param digits desired token digits count length - * @return \c true if token digits count length has been updated; \c false p + * @return \c true if token digits count length has been updated; \c false otherwise */ bool token_info_set_digits_from_int(TokenInfo* token_info, uint8_t digits); + +/** + * @brief Sets token duration from \c uint8_t value + * @param token_info instance whichs token digits count length should be updated + * @param duration desired token duration in seconds + * @return \c true if token duration has been updated; \c false otherwise + */ +bool token_info_set_duration_from_int(TokenInfo* token_info, uint8_t duration); diff --git a/applications/plugins/totp/ui/scenes/add_new_token/totp_scene_add_new_token.c b/applications/plugins/totp/ui/scenes/add_new_token/totp_scene_add_new_token.c index 592a12d0f4..f35f0238bc 100644 --- a/applications/plugins/totp/ui/scenes/add_new_token/totp_scene_add_new_token.c +++ b/applications/plugins/totp/ui/scenes/add_new_token/totp_scene_add_new_token.c @@ -21,6 +21,7 @@ typedef enum { TokenSecretTextBox, TokenAlgoSelect, TokenLengthSelect, + TokenDurationSelect, ConfirmButton, } Control; @@ -39,6 +40,8 @@ typedef struct { int16_t screen_y_offset; TokenHashAlgo algo; uint8_t digits_count_index; + uint8_t duration; + FuriString* duration_text; } SceneState; void totp_scene_add_new_token_init(const PluginState* plugin_state) { @@ -63,6 +66,10 @@ static void on_token_secret_user_comitted(InputTextSceneCallbackResult* result) free(result); } +static void update_duration_text(SceneState* scene_state) { + furi_string_printf(scene_state->duration_text, "%d sec.", scene_state->duration); +} + void totp_scene_add_new_token_activate( PluginState* plugin_state, const TokenAddEditSceneContext* context) { @@ -89,6 +96,9 @@ void totp_scene_add_new_token_activate( scene_state->screen_y_offset = 0; scene_state->input_state = NULL; + scene_state->duration = TOTP_TOKEN_DURATION_DEFAULT; + scene_state->duration_text = furi_string_alloc(); + update_duration_text(scene_state); if(context == NULL) { TOTP_NULLABLE_NULL(scene_state->current_token_index); @@ -124,14 +134,23 @@ void totp_scene_add_new_token_render(Canvas* const canvas, PluginState* plugin_s ui_control_select_render( canvas, 0, - 63 - scene_state->screen_y_offset, + 61 - scene_state->screen_y_offset, SCREEN_WIDTH, TOKEN_DIGITS_TEXT_LIST[scene_state->digits_count_index], scene_state->selected_control == TokenLengthSelect); + + ui_control_select_render( + canvas, + 0, + 78 - scene_state->screen_y_offset, + SCREEN_WIDTH, + furi_string_get_cstr(scene_state->duration_text), + scene_state->selected_control == TokenDurationSelect); + ui_control_button_render( canvas, SCREEN_WIDTH_CENTER - 24, - 85 - scene_state->screen_y_offset, + 101 - scene_state->screen_y_offset, 48, 13, "Confirm", @@ -146,8 +165,12 @@ void totp_scene_add_new_token_render(Canvas* const canvas, PluginState* plugin_s } void update_screen_y_offset(SceneState* scene_state) { - if(scene_state->selected_control > TokenAlgoSelect) { - scene_state->screen_y_offset = 35; + if(scene_state->selected_control > TokenLengthSelect) { + scene_state->screen_y_offset = 51; + } else if(scene_state->selected_control > TokenAlgoSelect) { + scene_state->screen_y_offset = 34; + } else if(scene_state->selected_control > TokenSecretTextBox) { + scene_state->screen_y_offset = 17; } else { scene_state->screen_y_offset = 0; } @@ -197,6 +220,9 @@ bool totp_scene_add_new_token_handle_event(PluginEvent* const event, PluginState } else if(scene_state->selected_control == TokenLengthSelect) { totp_roll_value_uint8_t( &scene_state->digits_count_index, 1, 0, 1, RollOverflowBehaviorRoll); + } else if(scene_state->selected_control == TokenDurationSelect) { + totp_roll_value_uint8_t(&scene_state->duration, 15, 15, 255, RollOverflowBehaviorStop); + update_duration_text(scene_state); } break; case InputKeyLeft: @@ -206,6 +232,10 @@ bool totp_scene_add_new_token_handle_event(PluginEvent* const event, PluginState } else if(scene_state->selected_control == TokenLengthSelect) { totp_roll_value_uint8_t( &scene_state->digits_count_index, -1, 0, 1, RollOverflowBehaviorRoll); + } else if(scene_state->selected_control == TokenDurationSelect) { + totp_roll_value_uint8_t( + &scene_state->duration, -15, 15, 255, RollOverflowBehaviorStop); + update_duration_text(scene_state); } break; case InputKeyOk: @@ -230,6 +260,8 @@ bool totp_scene_add_new_token_handle_event(PluginEvent* const event, PluginState break; case TokenLengthSelect: break; + case TokenDurationSelect: + break; case ConfirmButton: { TokenInfo* tokenInfo = token_info_alloc(); bool token_secret_set = token_info_set_secret( @@ -245,6 +277,7 @@ bool totp_scene_add_new_token_handle_event(PluginEvent* const event, PluginState tokenInfo->name, scene_state->token_name, scene_state->token_name_length + 1); tokenInfo->algo = scene_state->algo; tokenInfo->digits = TOKEN_DIGITS_VALUE_LIST[scene_state->digits_count_index]; + tokenInfo->duration = scene_state->duration; TOTP_LIST_INIT_OR_ADD(plugin_state->tokens_list, tokenInfo, furi_check); plugin_state->tokens_count++; @@ -310,6 +343,8 @@ void totp_scene_add_new_token_deactivate(PluginState* plugin_state) { free(scene_state->token_secret_input_context->header_text); free(scene_state->token_secret_input_context); + furi_string_free(scene_state->duration_text); + if(scene_state->input_state != NULL) { totp_input_text_free(scene_state->input_state); } diff --git a/applications/plugins/totp/ui/scenes/generate_token/totp_scene_generate_token.c b/applications/plugins/totp/ui/scenes/generate_token/totp_scene_generate_token.c index 00349ddc4c..41c52b435d 100644 --- a/applications/plugins/totp/ui/scenes/generate_token/totp_scene_generate_token.c +++ b/applications/plugins/totp/ui/scenes/generate_token/totp_scene_generate_token.c @@ -16,13 +16,11 @@ #include "../token_menu/totp_scene_token_menu.h" #include "../../../workers/type_code/type_code.h" -#define TOKEN_LIFETIME 30 - typedef struct { uint16_t current_token_index; char last_code[TOTP_TOKEN_DIGITS_MAX_COUNT + 1]; - char* last_code_name; bool need_token_update; + TokenInfo* current_token; uint32_t last_token_gen_time; TotpTypeCodeWorkerContext* type_code_worker_context; NotificationMessage const** notification_sequence_new_token; @@ -151,7 +149,7 @@ static void update_totp_params(PluginState* const plugin_state) { list_element_at(plugin_state->tokens_list, scene_state->current_token_index)->data; scene_state->need_token_update = true; - scene_state->last_code_name = tokenInfo->name; + scene_state->current_token = tokenInfo; } } @@ -229,7 +227,7 @@ void totp_scene_generate_token_render(Canvas* const canvas, PluginState* plugin_ furi_hal_rtc_get_datetime(&curr_dt); uint32_t curr_ts = furi_hal_rtc_datetime_to_timestamp(&curr_dt); - bool is_new_token_time = curr_ts % TOKEN_LIFETIME == 0; + bool is_new_token_time = curr_ts % scene_state->current_token->duration == 0; if(is_new_token_time && scene_state->last_token_gen_time != curr_ts) { scene_state->need_token_update = true; } @@ -238,10 +236,7 @@ void totp_scene_generate_token_render(Canvas* const canvas, PluginState* plugin_ scene_state->need_token_update = false; scene_state->last_token_gen_time = curr_ts; - const TokenInfo* tokenInfo = - (TokenInfo*)(list_element_at( - plugin_state->tokens_list, scene_state->current_token_index) - ->data); + const TokenInfo* tokenInfo = scene_state->current_token; if(tokenInfo->token != NULL && tokenInfo->token_length > 0) { furi_mutex_acquire( @@ -258,7 +253,7 @@ void totp_scene_generate_token_render(Canvas* const canvas, PluginState* plugin_ key_length, curr_ts, plugin_state->timezone_offset, - TOKEN_LIFETIME), + tokenInfo->duration), scene_state->last_code, tokenInfo->digits); memset_s(key, key_length, 0, key_length); @@ -279,7 +274,7 @@ void totp_scene_generate_token_render(Canvas* const canvas, PluginState* plugin_ } canvas_set_font(canvas, FontPrimary); - uint16_t token_name_width = canvas_string_width(canvas, scene_state->last_code_name); + uint16_t token_name_width = canvas_string_width(canvas, scene_state->current_token->name); if(SCREEN_WIDTH - token_name_width > 18) { canvas_draw_str_aligned( canvas, @@ -287,7 +282,7 @@ void totp_scene_generate_token_render(Canvas* const canvas, PluginState* plugin_ SCREEN_HEIGHT_CENTER - 20, AlignCenter, AlignCenter, - scene_state->last_code_name); + scene_state->current_token->name); } else { canvas_draw_str_aligned( canvas, @@ -295,7 +290,7 @@ void totp_scene_generate_token_render(Canvas* const canvas, PluginState* plugin_ SCREEN_HEIGHT_CENTER - 20, AlignLeft, AlignCenter, - scene_state->last_code_name); + scene_state->current_token->name); canvas_set_color(canvas, ColorWhite); canvas_draw_box(canvas, 0, SCREEN_HEIGHT_CENTER - 24, 9, 9); canvas_draw_box(canvas, SCREEN_WIDTH - 10, SCREEN_HEIGHT_CENTER - 24, 9, 9); @@ -313,6 +308,7 @@ void totp_scene_generate_token_render(Canvas* const canvas, PluginState* plugin_ const uint8_t BAR_MARGIN = 3; const uint8_t BAR_HEIGHT = 4; + const uint8_t TOKEN_LIFETIME = scene_state->current_token->duration; float percentDone = (float)(TOKEN_LIFETIME - curr_ts % TOKEN_LIFETIME) / (float)TOKEN_LIFETIME; uint8_t barWidth = (uint8_t)((float)(SCREEN_WIDTH - (BAR_MARGIN << 1)) * percentDone); uint8_t barX = ((SCREEN_WIDTH - (BAR_MARGIN << 1) - barWidth) >> 1) + BAR_MARGIN; diff --git a/applications/plugins/unitemp/assets/sherlok_53x45.png b/applications/plugins/unitemp/assets/sherlok_53x45.png index 65571203eb..1f258737e3 100644 Binary files a/applications/plugins/unitemp/assets/sherlok_53x45.png and b/applications/plugins/unitemp/assets/sherlok_53x45.png differ diff --git a/applications/plugins/unitemp/assets/sherlok_53x45_sfw.png b/applications/plugins/unitemp/assets/sherlok_53x45_sfw.png deleted file mode 100644 index 1f258737e3..0000000000 Binary files a/applications/plugins/unitemp/assets/sherlok_53x45_sfw.png and /dev/null differ diff --git a/applications/plugins/unitemp/views/General_view.c b/applications/plugins/unitemp/views/General_view.c index 02e416fb2f..e21b04de27 100644 --- a/applications/plugins/unitemp/views/General_view.c +++ b/applications/plugins/unitemp/views/General_view.c @@ -19,7 +19,6 @@ #include "unitemp_icons.h" #include -#include "../../../settings/desktop_settings/desktop_settings_app.h" static View* view; @@ -170,13 +169,7 @@ static void _draw_singleSensor(Canvas* canvas, Sensor* sensor, const uint8_t pos } static void _draw_view_noSensors(Canvas* canvas) { - DesktopSettings* settings = malloc(sizeof(DesktopSettings)); - DESKTOP_SETTINGS_LOAD(settings); - if(settings->sfw_mode) { - canvas_draw_icon(canvas, 7, 17, &I_sherlok_53x45_sfw); - } else { - canvas_draw_icon(canvas, 7, 17, &I_sherlok_53x45); - } + canvas_draw_icon(canvas, 7, 17, &I_sherlok_53x45); //Рисование рамки canvas_draw_rframe(canvas, 0, 0, 128, 63, 7); canvas_draw_rframe(canvas, 0, 0, 128, 64, 7); @@ -191,7 +184,6 @@ static void _draw_view_noSensors(Canvas* canvas) { canvas_draw_str(canvas, x, y + 18, "press OK"); canvas_draw_icon(canvas, x + 37, y + 10, &I_Ok_btn_9x9); - free(settings); } static void _draw_view_sensorsList(Canvas* canvas) { diff --git a/applications/plugins/weather_station/images/Scanning_123x52.png b/applications/plugins/weather_station/images/Scanning_123x52.png index a48c5330e8..ec785948d0 100644 Binary files a/applications/plugins/weather_station/images/Scanning_123x52.png and b/applications/plugins/weather_station/images/Scanning_123x52.png differ diff --git a/applications/plugins/weather_station/images/Scanning_123x52_sfw.png b/applications/plugins/weather_station/images/Scanning_123x52_sfw.png deleted file mode 100644 index ec785948d0..0000000000 Binary files a/applications/plugins/weather_station/images/Scanning_123x52_sfw.png and /dev/null differ diff --git a/applications/plugins/weather_station/images/WarningDolphin_45x42.png b/applications/plugins/weather_station/images/WarningDolphin_45x42.png index db225de36f..d766ffbb44 100644 Binary files a/applications/plugins/weather_station/images/WarningDolphin_45x42.png and b/applications/plugins/weather_station/images/WarningDolphin_45x42.png differ diff --git a/applications/plugins/weather_station/images/WarningDolphin_45x42_sfw.png b/applications/plugins/weather_station/images/WarningDolphin_45x42_sfw.png deleted file mode 100644 index d766ffbb44..0000000000 Binary files a/applications/plugins/weather_station/images/WarningDolphin_45x42_sfw.png and /dev/null differ diff --git a/applications/plugins/weather_station/views/weather_station_receiver.c b/applications/plugins/weather_station/views/weather_station_receiver.c index cfcdac9fba..42a90b22d9 100644 --- a/applications/plugins/weather_station/views/weather_station_receiver.c +++ b/applications/plugins/weather_station/views/weather_station_receiver.c @@ -7,8 +7,6 @@ #include #include -#include "../../../settings/desktop_settings/desktop_settings_app.h" - #define FRAME_HEIGHT 12 #define MAX_LEN_PX 112 #define MENU_ITEMS 4u @@ -178,9 +176,6 @@ void ws_view_receiver_draw(Canvas* canvas, WSReceiverModel* model) { FuriString* str_buff; str_buff = furi_string_alloc(); - DesktopSettings* settings = malloc(sizeof(DesktopSettings)); - DESKTOP_SETTINGS_LOAD(settings); - WSReceiverMenuItem* item_menu; for(size_t i = 0; i < MIN(model->history_item, MENU_ITEMS); ++i) { @@ -205,11 +200,7 @@ void ws_view_receiver_draw(Canvas* canvas, WSReceiverModel* model) { canvas_set_color(canvas, ColorBlack); if(model->history_item == 0) { - if(settings->sfw_mode) { - canvas_draw_icon(canvas, 0, 0, &I_Scanning_123x52_sfw); - } else { - canvas_draw_icon(canvas, 0, 0, &I_Scanning_123x52); - } + canvas_draw_icon(canvas, 0, 0, &I_Scanning_123x52); canvas_set_font(canvas, FontPrimary); canvas_draw_str(canvas, 63, 46, "Scanning..."); canvas_draw_line(canvas, 46, 51, 125, 51); @@ -231,11 +222,7 @@ void ws_view_receiver_draw(Canvas* canvas, WSReceiverModel* model) { canvas_draw_icon(canvas, 65, 42, &I_Pin_back_arrow_10x8); canvas_draw_icon(canvas, 80, 42, &I_Pin_back_arrow_10x8); canvas_draw_icon(canvas, 95, 42, &I_Pin_back_arrow_10x8); - if(settings->sfw_mode) { - canvas_draw_icon(canvas, 16, 13, &I_WarningDolphin_45x42_sfw); - } else { - canvas_draw_icon(canvas, 16, 13, &I_WarningDolphin_45x42); - } + canvas_draw_icon(canvas, 16, 13, &I_WarningDolphin_45x42); canvas_draw_dot(canvas, 17, 61); break; case WSReceiverBarShowUnlock: @@ -248,7 +235,6 @@ void ws_view_receiver_draw(Canvas* canvas, WSReceiverModel* model) { canvas_draw_str(canvas, 96, 62, furi_string_get_cstr(model->history_stat_str)); break; } - free(settings); } static void ws_view_receiver_timer_callback(void* context) { diff --git a/applications/services/bt/bt_service/bt.c b/applications/services/bt/bt_service/bt.c index e341544b32..1ca6a27752 100644 --- a/applications/services/bt/bt_service/bt.c +++ b/applications/services/bt/bt_service/bt.c @@ -5,7 +5,7 @@ #include #include #include -#include "../../../settings/desktop_settings/desktop_settings_app.h" +#include "../../../settings/xtreme_settings/xtreme_assets.h" #define TAG "BtSrv" @@ -36,17 +36,10 @@ static void bt_pin_code_view_port_draw_callback(Canvas* canvas, void* context) { furi_assert(context); Bt* bt = context; char pin_code_info[24]; - DesktopSettings* settings = malloc(sizeof(DesktopSettings)); - DESKTOP_SETTINGS_LOAD(settings); - if(settings->sfw_mode) { - canvas_draw_icon(canvas, 0, 0, &I_BLE_Pairing_128x64_sfw); - } else { - canvas_draw_icon(canvas, 0, 0, &I_BLE_Pairing_128x64); - } + canvas_draw_icon(canvas, 0, 0, XTREME_ASSETS()->I_BLE_Pairing_128x64); snprintf(pin_code_info, sizeof(pin_code_info), "Pairing code\n%06lu", bt->pin_code); elements_multiline_text_aligned(canvas, 64, 4, AlignCenter, AlignTop, pin_code_info); elements_button_left(canvas, "Quit"); - free(settings); } static void bt_pin_code_view_port_input_callback(InputEvent* event, void* context) { @@ -83,16 +76,10 @@ static void bt_pin_code_hide(Bt* bt) { static bool bt_pin_code_verify_event_handler(Bt* bt, uint32_t pin) { furi_assert(bt); - DesktopSettings* settings = malloc(sizeof(DesktopSettings)); - DESKTOP_SETTINGS_LOAD(settings); notification_message(bt->notification, &sequence_display_backlight_on); FuriString* pin_str; - if(settings->sfw_mode) { - dialog_message_set_icon(bt->dialog_message, &I_BLE_Pairing_128x64_sfw, 0, 0); - } else { - dialog_message_set_icon(bt->dialog_message, &I_BLE_Pairing_128x64, 0, 0); - } + dialog_message_set_icon(bt->dialog_message, XTREME_ASSETS()->I_BLE_Pairing_128x64, 0, 0); pin_str = furi_string_alloc_printf("Verify code\n%06lu", pin); dialog_message_set_text( bt->dialog_message, furi_string_get_cstr(pin_str), 64, 4, AlignCenter, AlignTop); @@ -100,7 +87,6 @@ static bool bt_pin_code_verify_event_handler(Bt* bt, uint32_t pin) { DialogMessageButton button = dialog_message_show(bt->dialogs, bt->dialog_message); furi_string_free(pin_str); return button == DialogMessageButtonCenter; - free(settings); } static void bt_battery_level_changed_callback(const void* _event, void* context) { diff --git a/applications/services/desktop/animations/animation_manager.c b/applications/services/desktop/animations/animation_manager.c index d3d85be43d..c1eb50d597 100644 --- a/applications/services/desktop/animations/animation_manager.c +++ b/applications/services/desktop/animations/animation_manager.c @@ -13,7 +13,7 @@ #include "animation_storage.h" #include "animation_manager.h" -#include "../../../settings/desktop_settings/desktop_settings_app.h" +#include "../../../settings/xtreme_settings/xtreme_settings.h" #define TAG "AnimationManager" @@ -54,7 +54,6 @@ struct AnimationManager { FuriString* freezed_animation_name; int32_t freezed_animation_time_left; ViewStack* view_stack; - bool sfw_mode; }; static StorageAnimation* @@ -66,7 +65,8 @@ static void animation_manager_start_new_idle(AnimationManager* animation_manager static bool animation_manager_check_blocking(AnimationManager* animation_manager); static bool animation_manager_is_valid_idle_animation( const StorageAnimationManifestInfo* info, - const DolphinStats* stats); + const DolphinStats* stats, + const bool unlock); static void animation_manager_switch_to_one_shot_view(AnimationManager* animation_manager); static void animation_manager_switch_to_animation_view(AnimationManager* animation_manager); @@ -145,7 +145,7 @@ void animation_manager_check_blocking_process(AnimationManager* animation_manage const StorageAnimationManifestInfo* manifest_info = animation_storage_get_meta(animation_manager->current_animation); - bool valid = animation_manager_is_valid_idle_animation(manifest_info, &stats); + bool valid = animation_manager_is_valid_idle_animation(manifest_info, &stats, XTREME_SETTINGS()->unlock_anims); if(!valid) { animation_manager_start_new_idle(animation_manager); @@ -200,11 +200,9 @@ static void animation_manager_start_new_idle(AnimationManager* animation_manager const BubbleAnimation* bubble_animation = animation_storage_get_bubble_animation(animation_manager->current_animation); animation_manager->state = AnimationManagerStateIdle; - DesktopSettings* settings = malloc(sizeof(DesktopSettings)); - DESKTOP_SETTINGS_LOAD(settings); - int32_t duration_s = settings->cycle_animation_s == -1 ? bubble_animation->duration : (settings->cycle_animation_s - 1); - furi_timer_start(animation_manager->idle_animation_timer, duration_s * 1000); - free(settings); + XtremeSettings* xtreme_settings = XTREME_SETTINGS(); + int32_t duration = (xtreme_settings->cycle_anims == 0) ? (bubble_animation->duration) : (xtreme_settings->cycle_anims); + furi_timer_start(animation_manager->idle_animation_timer, (duration > 0) ? (duration * 1000) : 0); } static bool animation_manager_check_blocking(AnimationManager* animation_manager) { @@ -336,7 +334,8 @@ View* animation_manager_get_animation_view(AnimationManager* animation_manager) static bool animation_manager_is_valid_idle_animation( const StorageAnimationManifestInfo* info, - const DolphinStats* stats) { + const DolphinStats* stats, + const bool unlock) { furi_assert(info); furi_assert(info->name); @@ -356,11 +355,13 @@ static bool animation_manager_is_valid_idle_animation( result = (sd_status == FSE_NOT_READY); } - if((stats->butthurt < info->min_butthurt) || (stats->butthurt > info->max_butthurt)) { - result = false; - } - if((stats->level < info->min_level) || (stats->level > info->max_level)) { - result = false; + if (!unlock) { + if((stats->butthurt < info->min_butthurt) || (stats->butthurt > info->max_butthurt)) { + result = false; + } + if((stats->level < info->min_level) || (stats->level > info->max_level)) { + result = false; + } } return result; @@ -368,7 +369,10 @@ static bool animation_manager_is_valid_idle_animation( static StorageAnimation* animation_manager_select_idle_animation(AnimationManager* animation_manager) { - UNUSED(animation_manager); + const char* old_animation_name = NULL; + if (animation_manager->current_animation) { + old_animation_name = animation_storage_get_meta(animation_manager->current_animation)->name; + } StorageAnimationList_t animation_list; StorageAnimationList_init(animation_list); @@ -380,11 +384,18 @@ static StorageAnimation* uint32_t whole_weight = 0; StorageAnimationList_it_t it; + bool unlock = XTREME_SETTINGS()->unlock_anims; for(StorageAnimationList_it(it, animation_list); !StorageAnimationList_end_p(it);) { StorageAnimation* storage_animation = *StorageAnimationList_ref(it); const StorageAnimationManifestInfo* manifest_info = animation_storage_get_meta(storage_animation); - bool valid = animation_manager_is_valid_idle_animation(manifest_info, &stats); + bool valid = animation_manager_is_valid_idle_animation(manifest_info, &stats, unlock); + + if (old_animation_name != NULL) { + if (strcmp(manifest_info->name, old_animation_name) == 0) { + valid = false; + } + } if(valid) { whole_weight += manifest_info->weight; @@ -396,7 +407,7 @@ static StorageAnimation* } } - uint32_t lucky_number = furi_hal_random_get() % whole_weight; + uint32_t lucky_number = furi_hal_random_get() % (whole_weight != 0 ? whole_weight : 1); uint32_t weight = 0; StorageAnimation* selected = NULL; @@ -501,7 +512,7 @@ void animation_manager_load_and_continue_animation(AnimationManager* animation_m furi_record_close(RECORD_DOLPHIN); const StorageAnimationManifestInfo* manifest_info = animation_storage_get_meta(restore_animation); - bool valid = animation_manager_is_valid_idle_animation(manifest_info, &stats); + bool valid = animation_manager_is_valid_idle_animation(manifest_info, &stats, XTREME_SETTINGS()->unlock_anims); if(valid) { animation_manager_replace_current_animation( animation_manager, restore_animation); @@ -512,14 +523,12 @@ void animation_manager_load_and_continue_animation(AnimationManager* animation_m animation_manager->idle_animation_timer, animation_manager->freezed_animation_time_left); } else { - const BubbleAnimation* animation = animation_storage_get_bubble_animation( + const BubbleAnimation* bubble_animation = animation_storage_get_bubble_animation( animation_manager->current_animation); - DesktopSettings* settings = malloc(sizeof(DesktopSettings)); - DESKTOP_SETTINGS_LOAD(settings); - int32_t duration_s = settings->cycle_animation_s == -1 ? animation->duration : (settings->cycle_animation_s - 1); + XtremeSettings* xtreme_settings = XTREME_SETTINGS(); + int32_t duration = (xtreme_settings->cycle_anims == 0) ? (bubble_animation->duration) : (xtreme_settings->cycle_anims); furi_timer_start( - animation_manager->idle_animation_timer, duration_s * 1000); - free(settings); + animation_manager->idle_animation_timer, (duration > 0) ? (duration * 1000) : 0); } } } else { @@ -554,8 +563,6 @@ static void animation_manager_switch_to_one_shot_view(AnimationManager* animatio Dolphin* dolphin = furi_record_open(RECORD_DOLPHIN); DolphinStats stats = dolphin_stats(dolphin); furi_record_close(RECORD_DOLPHIN); - DesktopSettings* settings = malloc(sizeof(DesktopSettings)); - DESKTOP_SETTINGS_LOAD(settings); animation_manager->one_shot_view = one_shot_view_alloc(); one_shot_view_set_interact_callback( @@ -564,7 +571,9 @@ static void animation_manager_switch_to_one_shot_view(AnimationManager* animatio View* next_view = one_shot_view_get_view(animation_manager->one_shot_view); view_stack_remove_view(animation_manager->view_stack, prev_view); view_stack_add_view(animation_manager->view_stack, next_view); - if(settings->sfw_mode) { + if(XTREME_SETTINGS()->nsfw_mode) { + one_shot_view_start_animation(animation_manager->one_shot_view, &A_Levelup1_128x64); + } else { if(stats.level <= 20) { one_shot_view_start_animation( animation_manager->one_shot_view, &A_Levelup1_128x64_sfw); @@ -574,10 +583,7 @@ static void animation_manager_switch_to_one_shot_view(AnimationManager* animatio } else { furi_assert(0); } - } else { - one_shot_view_start_animation(animation_manager->one_shot_view, &A_Levelup1_128x64); } - free(settings); } static void animation_manager_switch_to_animation_view(AnimationManager* animation_manager) { diff --git a/applications/services/desktop/animations/animation_storage.c b/applications/services/desktop/animations/animation_storage.c index c1dcdffc34..28cdfe8102 100644 --- a/applications/services/desktop/animations/animation_storage.c +++ b/applications/services/desktop/animations/animation_storage.c @@ -11,43 +11,63 @@ #include "animation_storage_i.h" #include #include -#include "../../../settings/desktop_settings/desktop_settings_app.h" +#include "../../../settings/xtreme_settings/xtreme_assets.h" #define ANIMATION_META_FILE "meta.txt" -#define ANIMATION_DIR EXT_PATH("dolphin") +#define BASE_ANIMATION_DIR EXT_PATH("dolphin") #define TAG "AnimationStorage" /* Unused old code, for safe-keeping #define ANIMATION_MANIFEST_FILE ANIMATION_DIR "/manifest.txt" */ -char ANIMATION_MANIFEST_FILE[30]; +// 59 Max length = strlen("/ext/dolphin_custom//Anims") + MAX_PACK_NAME_LEN + 1 (Null terminator) +char ANIMATION_DIR[59]; +// 72 Max length = ANIMATION_DIR + strlen("/manifest.txt") +char ANIMATION_MANIFEST_FILE[72]; static void animation_storage_free_bubbles(BubbleAnimation* animation); static void animation_storage_free_frames(BubbleAnimation* animation); static void animation_storage_free_animation(BubbleAnimation** storage_animation); static BubbleAnimation* animation_storage_load_animation(const char* name); -void animation_handler_beta() { - DesktopSettings* settings = malloc(sizeof(DesktopSettings)); - DESKTOP_SETTINGS_LOAD(settings); - - if(settings->sfw_mode) { - snprintf(ANIMATION_MANIFEST_FILE, sizeof(ANIMATION_DIR), "%s", ANIMATION_DIR); - FURI_LOG_I(TAG, "SFW Manifest selected"); - strcat(ANIMATION_MANIFEST_FILE, "/sfw/manifest.txt"); - } else { - snprintf(ANIMATION_MANIFEST_FILE, sizeof(ANIMATION_DIR), "%s", ANIMATION_DIR); - FURI_LOG_I(TAG, "NSFW Manifest selected"); - strcat(ANIMATION_MANIFEST_FILE, "/nsfw/manifest.txt"); +void animation_handler_select_manifest() { + XtremeSettings* xtreme_settings = XTREME_SETTINGS(); + FuriString* anim_dir = furi_string_alloc(); + FuriString* manifest = furi_string_alloc(); + bool use_asset_pack = xtreme_settings->asset_pack[0] != '\0'; + if (use_asset_pack) { + furi_string_printf(anim_dir, "%s/%s/Anims", PACKS_DIR, xtreme_settings->asset_pack); + furi_string_printf(manifest, "%s/manifest.txt", furi_string_get_cstr(anim_dir)); + Storage* storage = furi_record_open(RECORD_STORAGE); + if (storage_common_stat(storage, furi_string_get_cstr(manifest), NULL) == FSE_OK) { + FURI_LOG_I(TAG, "Custom Manifest selected"); + } else { + use_asset_pack = false; + } + furi_record_close(RECORD_STORAGE); + } + if (!use_asset_pack) { + furi_string_set(anim_dir, BASE_ANIMATION_DIR); + if(xtreme_settings->nsfw_mode) { + furi_string_cat_str(anim_dir, "/nsfw"); + FURI_LOG_I(TAG, "NSFW Manifest selected"); + } else { + furi_string_cat_str(anim_dir, "/sfw"); + FURI_LOG_I(TAG, "SFW Manifest selected"); + } + furi_string_printf(manifest, "%s/manifest.txt", furi_string_get_cstr(anim_dir)); } - free(settings); + strlcpy(ANIMATION_DIR, furi_string_get_cstr(anim_dir), sizeof(ANIMATION_DIR)); + strlcpy(ANIMATION_MANIFEST_FILE, furi_string_get_cstr(manifest), sizeof(ANIMATION_MANIFEST_FILE)); + furi_string_free(manifest); + furi_string_free(anim_dir); } static bool animation_storage_load_single_manifest_info( StorageAnimationManifestInfo* manifest_info, const char* name) { furi_assert(manifest_info); - animation_handler_beta(); + animation_handler_select_manifest(); bool result = false; Storage* storage = furi_record_open(RECORD_STORAGE); FlipperFormat* file = flipper_format_file_alloc(storage); @@ -103,7 +123,7 @@ static bool animation_storage_load_single_manifest_info( void animation_storage_fill_animation_list(StorageAnimationList_t* animation_list) { furi_assert(sizeof(StorageAnimationList_t) == sizeof(void*)); furi_assert(!StorageAnimationList_size(*animation_list)); - animation_handler_beta(); + animation_handler_select_manifest(); Storage* storage = furi_record_open(RECORD_STORAGE); FlipperFormat* file = flipper_format_file_alloc(storage); @@ -319,7 +339,7 @@ static bool animation_storage_load_frames( for(int i = 0; i < icon->frame_count; ++i) { frames_ok = false; - furi_string_printf(filename, ANIMATION_DIR "/%s/frame_%d.bm", name, i); + furi_string_printf(filename, "%s/%s/frame_%d.bm", ANIMATION_DIR, name, i); if(storage_common_stat(storage, furi_string_get_cstr(filename), &file_info) != FSE_OK) break; @@ -471,7 +491,7 @@ static BubbleAnimation* animation_storage_load_animation(const char* name) { if(FSE_OK != storage_sd_status(storage)) break; - furi_string_printf(str, ANIMATION_DIR "/%s/" ANIMATION_META_FILE, name); + furi_string_printf(str, "%s/%s/" ANIMATION_META_FILE, ANIMATION_DIR, name); if(!flipper_format_file_open_existing(ff, furi_string_get_cstr(str))) break; if(!flipper_format_read_header(ff, str, &u32value)) break; if(furi_string_cmp_str(str, "Flipper Animation")) break; @@ -505,6 +525,11 @@ static BubbleAnimation* animation_storage_load_animation(const char* name) { if(!flipper_format_read_uint32(ff, "Active cycles", &u32value, 1)) break; //-V779 animation->active_cycles = u32value; if(!flipper_format_read_uint32(ff, "Frame rate", &u32value, 1)) break; + uint16_t anim_speed = XTREME_SETTINGS()->anim_speed; + anim_speed = (anim_speed == 0 ? 100 : anim_speed); + u32value = (u32value * anim_speed) / 100; + u32value = u32value < 1 ? 1 : u32value; + u32value = u32value > 10 ? 10 : u32value; FURI_CONST_ASSIGN(animation->icon_animation.frame_rate, u32value); if(!flipper_format_read_uint32(ff, "Duration", &u32value, 1)) break; animation->duration = u32value; diff --git a/applications/services/desktop/animations/views/bubble_animation_view.c b/applications/services/desktop/animations/views/bubble_animation_view.c index 607862d113..3cef74a81f 100644 --- a/applications/services/desktop/animations/views/bubble_animation_view.c +++ b/applications/services/desktop/animations/views/bubble_animation_view.c @@ -12,6 +12,7 @@ #include #include #include +#include #define ACTIVE_SHIFT 2 @@ -133,6 +134,10 @@ static bool bubble_animation_input_callback(InputEvent* event, void* context) { if(animation_view->interact_callback) { animation_view->interact_callback(animation_view->interact_callback_context); } + } else if(event->type == InputTypeLong) { + Loader* loader = furi_record_open(RECORD_LOADER); + loader_start(loader, "About", "batt"); + furi_record_close(RECORD_LOADER); } } diff --git a/applications/services/desktop/animations/views/one_shot_animation_view.c b/applications/services/desktop/animations/views/one_shot_animation_view.c index 9a4dff06c5..d12c4ccbed 100644 --- a/applications/services/desktop/animations/views/one_shot_animation_view.c +++ b/applications/services/desktop/animations/views/one_shot_animation_view.c @@ -6,6 +6,7 @@ #include #include #include +#include typedef void (*OneShotInteractCallback)(void*); @@ -70,6 +71,10 @@ static bool one_shot_view_input(InputEvent* event, void* context) { if(view->interact_callback) { view->interact_callback(view->interact_callback_context); } + } else if(event->type == InputTypeLong) { + Loader* loader = furi_record_open(RECORD_LOADER); + loader_start(loader, "About", "batt"); + furi_record_close(RECORD_LOADER); } } } diff --git a/applications/services/desktop/desktop.c b/applications/services/desktop/desktop.c index 78ff9bdab5..7840cd00a8 100644 --- a/applications/services/desktop/desktop.c +++ b/applications/services/desktop/desktop.c @@ -140,12 +140,6 @@ void desktop_unlock(Desktop* desktop) { desktop_auto_lock_arm(desktop); } -void desktop_set_sfw_mode_state(Desktop* desktop, bool enabled) { - desktop->settings.sfw_mode = enabled; - DESKTOP_SETTINGS_SAVE(&desktop->settings); - animation_manager_new_idle_process(desktop->animation_manager); -} - Desktop* desktop_alloc() { Desktop* desktop = malloc(sizeof(Desktop)); @@ -322,13 +316,6 @@ int32_t desktop_srv(void* p) { DESKTOP_SETTINGS_SAVE(&desktop->settings); } - if(!desktop->settings.cycle_animation_s) { - desktop->settings.cycle_animation_s = -1; - DESKTOP_SETTINGS_SAVE(&desktop->settings); - } - - desktop_main_set_sfw_mode_state(desktop->main_view, desktop->settings.sfw_mode); - scene_manager_next_scene(desktop->scene_manager, DesktopSceneMain); desktop_pin_lock_init(&desktop->settings); diff --git a/applications/services/desktop/desktop_i.h b/applications/services/desktop/desktop_i.h index 007c50f364..2bb0d683f1 100644 --- a/applications/services/desktop/desktop_i.h +++ b/applications/services/desktop/desktop_i.h @@ -75,4 +75,3 @@ Desktop* desktop_alloc(); void desktop_free(Desktop* desktop); void desktop_lock(Desktop* desktop); void desktop_unlock(Desktop* desktop); -void desktop_set_sfw_mode_state(Desktop* desktop, bool enabled); diff --git a/applications/services/desktop/desktop_settings.h b/applications/services/desktop/desktop_settings.h index 5e97f76476..6285f9c908 100644 --- a/applications/services/desktop/desktop_settings.h +++ b/applications/services/desktop/desktop_settings.h @@ -36,13 +36,6 @@ #define MIN_PIN_SIZE 4 #define MAX_APP_LENGTH 128 -#define DISPLAY_BATTERY_BAR 0 -#define DISPLAY_BATTERY_PERCENT 1 -#define DISPLAY_BATTERY_INVERTED_PERCENT 2 -#define DISPLAY_BATTERY_RETRO_3 3 -#define DISPLAY_BATTERY_RETRO_5 4 -#define DISPLAY_BATTERY_BAR_PERCENT 5 - #define FAP_LOADER_APP_NAME "Applications" typedef struct { @@ -61,8 +54,4 @@ typedef struct { PinCode pin_code; uint8_t is_locked; uint32_t auto_lock_delay_ms; - uint8_t displayBatteryPercentage; - bool is_sfwmode; - uint8_t sfw_mode; - int32_t cycle_animation_s; } DesktopSettings; diff --git a/applications/services/desktop/scenes/desktop_scene_fault.c b/applications/services/desktop/scenes/desktop_scene_fault.c index 79dedbe59f..e4f5e788f7 100644 --- a/applications/services/desktop/scenes/desktop_scene_fault.c +++ b/applications/services/desktop/scenes/desktop_scene_fault.c @@ -1,7 +1,7 @@ #include #include "../desktop_i.h" -#include "../../../settings/desktop_settings/desktop_settings_app.h" +#include "../../../settings/xtreme_settings/xtreme_settings.h" #define DesktopFaultEventExit 0x00FF00FF @@ -13,15 +13,12 @@ void desktop_scene_fault_callback(void* context) { void desktop_scene_fault_on_enter(void* context) { Desktop* desktop = (Desktop*)context; - DesktopSettings* settings = malloc(sizeof(DesktopSettings)); - DESKTOP_SETTINGS_LOAD(settings); - Popup* popup = desktop->hw_mismatch_popup; popup_set_context(popup, desktop); - if(settings->sfw_mode) { + if(XTREME_SETTINGS()->nsfw_mode) { popup_set_header( popup, - "Flipper crashed\n but has been rebooted", + "Slut passed out\n but is now back", 60, 14 + STATUS_BAR_Y_SHIFT, AlignCenter, @@ -29,7 +26,7 @@ void desktop_scene_fault_on_enter(void* context) { } else { popup_set_header( popup, - "Slut passed out\n but is now back", + "Flipper crashed\n but has been rebooted", 60, 14 + STATUS_BAR_Y_SHIFT, AlignCenter, @@ -40,7 +37,6 @@ void desktop_scene_fault_on_enter(void* context) { popup_set_text(popup, message, 60, 37 + STATUS_BAR_Y_SHIFT, AlignCenter, AlignCenter); popup_set_callback(popup, desktop_scene_fault_callback); view_dispatcher_switch_to_view(desktop->view_dispatcher, DesktopViewIdHwMismatch); - free(settings); } bool desktop_scene_fault_on_event(void* context, SceneManagerEvent event) { diff --git a/applications/services/desktop/scenes/desktop_scene_lock_menu.c b/applications/services/desktop/scenes/desktop_scene_lock_menu.c index d56cabb30e..e55fe252e4 100644 --- a/applications/services/desktop/scenes/desktop_scene_lock_menu.c +++ b/applications/services/desktop/scenes/desktop_scene_lock_menu.c @@ -26,7 +26,6 @@ void desktop_scene_lock_menu_on_enter(void* context) { scene_manager_set_scene_state(desktop->scene_manager, DesktopSceneLockMenu, 0); desktop_lock_menu_set_callback(desktop->lock_menu, desktop_scene_lock_menu_callback, desktop); desktop_lock_menu_set_pin_state(desktop->lock_menu, desktop->settings.pin_code.length > 0); - desktop_lock_menu_set_sfw_mode_state(desktop->lock_menu, desktop->settings.sfw_mode); desktop_lock_menu_set_idx(desktop->lock_menu, 0); view_dispatcher_switch_to_view(desktop->view_dispatcher, DesktopViewIdLockMenu); @@ -90,15 +89,8 @@ bool desktop_scene_lock_menu_on_event(void* context, SceneManagerEvent event) { furi_record_close(RECORD_POWER); break; - case DesktopLockMenuEventSFWModeOn: - desktop_set_sfw_mode_state(desktop, true); - scene_manager_search_and_switch_to_previous_scene( - desktop->scene_manager, DesktopSceneMain); - break; - case DesktopLockMenuEventSFWModeOff: - desktop_set_sfw_mode_state(desktop, false); - scene_manager_search_and_switch_to_previous_scene( - desktop->scene_manager, DesktopSceneMain); + case DesktopLockMenuEventXtremeSettings: + loader_start(desktop->loader, "Xtreme FW", NULL); break; default: break; @@ -111,4 +103,4 @@ bool desktop_scene_lock_menu_on_event(void* context, SceneManagerEvent event) { void desktop_scene_lock_menu_on_exit(void* context) { UNUSED(context); -} \ No newline at end of file +} diff --git a/applications/services/desktop/views/desktop_events.h b/applications/services/desktop/views/desktop_events.h index 82ca43c4cf..a17114ad27 100644 --- a/applications/services/desktop/views/desktop_events.h +++ b/applications/services/desktop/views/desktop_events.h @@ -43,8 +43,7 @@ typedef enum { DesktopLockMenuEventPinLock, DesktopLockMenuEventPinLockShutdown, DesktopLockMenuEventExit, - DesktopLockMenuEventSFWModeOn, - DesktopLockMenuEventSFWModeOff, + DesktopLockMenuEventXtremeSettings, DesktopAnimationEventCheckAnimation, DesktopAnimationEventNewIdleAnimation, diff --git a/applications/services/desktop/views/desktop_view_lock_menu.c b/applications/services/desktop/views/desktop_view_lock_menu.c index 698c265057..4cdfa54da0 100644 --- a/applications/services/desktop/views/desktop_view_lock_menu.c +++ b/applications/services/desktop/views/desktop_view_lock_menu.c @@ -5,7 +5,7 @@ #include "../desktop_i.h" #include "desktop_view_lock_menu.h" -#include "applications/settings/desktop_settings/desktop_settings_app.h" +#include "../../../settings/xtreme_settings/xtreme_settings.h" #define LOCK_MENU_ITEMS_NB 5 @@ -13,7 +13,7 @@ typedef enum { DesktopLockMenuIndexLock, DesktopLockMenuIndexPinLock, DesktopLockMenuIndexPinLockShutdown, - DesktopLockMenuIndexSFW, + DesktopLockMenuIndexXtremeSettings, DesktopLockMenuIndexTotalCount } DesktopLockMenuIndex; @@ -36,11 +36,6 @@ void desktop_lock_menu_set_pin_state(DesktopLockMenuView* lock_menu, bool pin_is true); } -void desktop_lock_menu_set_sfw_mode_state(DesktopLockMenuView* lock_menu, bool sfw_mode) { - with_view_model( - lock_menu->view, DesktopLockMenuViewModel * model, { model->sfw_mode = sfw_mode; }, true); -} - void desktop_lock_menu_set_idx(DesktopLockMenuView* lock_menu, uint8_t idx) { furi_assert(idx < DesktopLockMenuIndexTotalCount); with_view_model( @@ -72,12 +67,8 @@ void desktop_lock_menu_draw_callback(Canvas* canvas, void* model) { } else { str = "Set PIN + Off"; } - } else if(i == DesktopLockMenuIndexSFW) { - if(m->sfw_mode) { - str = "NSFW Mode"; - } else { - str = "SFW Mode"; - } + } else if(i == DesktopLockMenuIndexXtremeSettings) { + str = "Xtreme Settings"; } if(str) //-V547 @@ -100,7 +91,6 @@ bool desktop_lock_menu_input_callback(InputEvent* event, void* context) { DesktopLockMenuView* lock_menu = context; uint8_t idx = 0; bool consumed = false; - bool sfw_mode = false; bool update = false; with_view_model( @@ -127,7 +117,6 @@ bool desktop_lock_menu_input_callback(InputEvent* event, void* context) { } } idx = model->idx; - sfw_mode = model->sfw_mode; }, update); @@ -138,17 +127,8 @@ bool desktop_lock_menu_input_callback(InputEvent* event, void* context) { lock_menu->callback(DesktopLockMenuEventPinLock, lock_menu->context); } else if((idx == DesktopLockMenuIndexPinLockShutdown) && (event->type == InputTypeShort)) { lock_menu->callback(DesktopLockMenuEventPinLockShutdown, lock_menu->context); - // } else if((idx == DesktopLockMenuIndexGameMode) && (event->type == InputTypeShort)) { - // desktop_view_lock_menu_sfwmode_changed(1); - // DOLPHIN_DEED(getRandomDeed()); - // lock_menu->callback(DesktopLockMenuEventExit, lock_menu->context); - } else if(idx == DesktopLockMenuIndexSFW) { - // DOLPHIN_DEED(getRandomDeed()); - if((sfw_mode == false) && (event->type == InputTypeShort)) { - lock_menu->callback(DesktopLockMenuEventSFWModeOn, lock_menu->context); - } else if((sfw_mode == true) && (event->type == InputTypeShort)) { - lock_menu->callback(DesktopLockMenuEventSFWModeOff, lock_menu->context); - } + } else if((idx == DesktopLockMenuIndexXtremeSettings) && (event->type == InputTypeShort)) { + lock_menu->callback(DesktopLockMenuEventXtremeSettings, lock_menu->context); } consumed = true; } diff --git a/applications/services/desktop/views/desktop_view_lock_menu.h b/applications/services/desktop/views/desktop_view_lock_menu.h index b05ef25aeb..da144d1f3c 100644 --- a/applications/services/desktop/views/desktop_view_lock_menu.h +++ b/applications/services/desktop/views/desktop_view_lock_menu.h @@ -18,7 +18,6 @@ struct DesktopLockMenuView { typedef struct { uint8_t idx; bool pin_is_set; - bool sfw_mode; } DesktopLockMenuViewModel; void desktop_lock_menu_set_callback( @@ -28,7 +27,6 @@ void desktop_lock_menu_set_callback( View* desktop_lock_menu_get_view(DesktopLockMenuView* lock_menu); void desktop_lock_menu_set_pin_state(DesktopLockMenuView* lock_menu, bool pin_is_set); -void desktop_lock_menu_set_sfw_mode_state(DesktopLockMenuView* lock_menu, bool sfw_mode); void desktop_lock_menu_set_idx(DesktopLockMenuView* lock_menu, uint8_t idx); DesktopLockMenuView* desktop_lock_menu_alloc(); void desktop_lock_menu_free(DesktopLockMenuView* lock_menu); diff --git a/applications/services/desktop/views/desktop_view_main.c b/applications/services/desktop/views/desktop_view_main.c index c3bb925555..9149fd5625 100644 --- a/applications/services/desktop/views/desktop_view_main.c +++ b/applications/services/desktop/views/desktop_view_main.c @@ -14,7 +14,6 @@ struct DesktopMainView { DesktopMainViewCallback callback; void* context; TimerHandle_t poweroff_timer; - bool sfw_mode; }; #define DESKTOP_MAIN_VIEW_POWEROFF_TIMEOUT 2000 @@ -39,11 +38,6 @@ View* desktop_main_get_view(DesktopMainView* main_view) { return main_view->view; } -void desktop_main_set_sfw_mode_state(DesktopMainView* main_view, bool sfw_mode) { - furi_assert(main_view); - main_view->sfw_mode = sfw_mode; -} - bool desktop_main_input_callback(InputEvent* event, void* context) { furi_assert(event); furi_assert(context); @@ -69,7 +63,7 @@ bool desktop_main_input_callback(InputEvent* event, void* context) { } else if(event->key == InputKeyDown) { main_view->callback(DesktopMainEventOpenFavoriteSecondary, main_view->context); } else if(event->key == InputKeyLeft) { - main_view->callback(DesktopMainEventLock, main_view->context); // OPENS SUBGHZ REMOTE + main_view->callback(DesktopMainEventLock, main_view->context); } } @@ -110,4 +104,4 @@ void desktop_main_free(DesktopMainView* main_view) { view_free(main_view->view); furi_timer_free(main_view->poweroff_timer); free(main_view); -} \ No newline at end of file +} diff --git a/applications/services/desktop/views/desktop_view_main.h b/applications/services/desktop/views/desktop_view_main.h index bf4f918bf3..329d954868 100644 --- a/applications/services/desktop/views/desktop_view_main.h +++ b/applications/services/desktop/views/desktop_view_main.h @@ -13,6 +13,5 @@ void desktop_main_set_callback( void* context); View* desktop_main_get_view(DesktopMainView* main_view); -void desktop_main_set_sfw_mode_state(DesktopMainView* main_view, bool sfw_mode); DesktopMainView* desktop_main_alloc(); void desktop_main_free(DesktopMainView* main_view); diff --git a/applications/services/dolphin/helpers/dolphin_state.c b/applications/services/dolphin/helpers/dolphin_state.c index e0e5dbe60f..72fa75ac06 100644 --- a/applications/services/dolphin/helpers/dolphin_state.c +++ b/applications/services/dolphin/helpers/dolphin_state.c @@ -14,9 +14,10 @@ #define DOLPHIN_STATE_PATH INT_PATH(DOLPHIN_STATE_FILE_NAME) #define DOLPHIN_STATE_HEADER_MAGIC 0xD0 #define DOLPHIN_STATE_HEADER_VERSION 0x01 -int level_array[30] = {100, 200, 300, 450, 600, 750, 950, 1150, 1350, 1600, - 1850, 2100, 2400, 2700, 3000, 3350, 3700, 4050, 4450, 4850, - 5250, 5700, 6150, 6600, 7100, 7600, 8100, 8650, 9200}; + +const int DOLPHIN_LEVELS[DOLPHIN_LEVEL_COUNT] = {100, 200, 300, 450, 600, 750, 950, 1150, 1350, 1600, + 1850, 2100, 2400, 2700, 3000, 3350, 3700, 4050, 4450, 4850, + 5250, 5700, 6150, 6600, 7100, 7600, 8100, 8650, 9200}; #define BUTTHURT_MAX 14 #define BUTTHURT_MIN 0 @@ -82,39 +83,43 @@ uint64_t dolphin_state_timestamp() { } bool dolphin_state_is_levelup(int icounter) { - for(int i = 0; i < 30; ++i) { - if((icounter == level_array[i])) { + for(int i = 0; i < DOLPHIN_LEVEL_COUNT; ++i) { + if((icounter == DOLPHIN_LEVELS[i])) { return true; } }; return false; } +const int* dolphin_get_levels() { + return DOLPHIN_LEVELS; +} + uint8_t dolphin_get_level(int icounter) { - for(int i = 0; i < 29; ++i) { - if(icounter <= level_array[i]) { + for(int i = 0; i < DOLPHIN_LEVEL_COUNT; ++i) { + if(icounter <= DOLPHIN_LEVELS[i]) { return i + 1; } } - return 30; + return DOLPHIN_LEVEL_COUNT + 1; } uint32_t dolphin_state_xp_above_last_levelup(int icounter) { - for(int i = 1; i < 29; ++i) { - if(icounter <= level_array[i]) { - return icounter - level_array[i - 1]; + for(int i = DOLPHIN_LEVEL_COUNT; i >= 0; --i) { + if(icounter >= DOLPHIN_LEVELS[i]) { + return icounter - DOLPHIN_LEVELS[i]; } } return icounter; } uint32_t dolphin_state_xp_to_levelup(int icounter) { - for(int i = 0; i < 29; ++i) { - if(icounter <= level_array[i]) { - return level_array[i] - icounter; + for(int i = 0; i < DOLPHIN_LEVEL_COUNT; ++i) { + if(icounter <= DOLPHIN_LEVELS[i]) { + return DOLPHIN_LEVELS[i] - icounter; } } - return (uint32_t)-1 - icounter; + return (uint32_t)-1; } void dolphin_state_on_deed(DolphinState* dolphin_state, DolphinDeed deed) { @@ -198,4 +203,4 @@ void dolphin_state_clear_limits(DolphinState* dolphin_state) { } dolphin_state->data.butthurt_daily_limit = 0; dolphin_state->dirty = true; -} \ No newline at end of file +} diff --git a/applications/services/dolphin/helpers/dolphin_state.h b/applications/services/dolphin/helpers/dolphin_state.h index edd7878e90..e0c6af1ef2 100644 --- a/applications/services/dolphin/helpers/dolphin_state.h +++ b/applications/services/dolphin/helpers/dolphin_state.h @@ -5,6 +5,8 @@ #include #include +#define DOLPHIN_LEVEL_COUNT 29 + typedef struct DolphinState DolphinState; typedef struct { uint8_t icounter_daily_limit[DolphinAppMAX]; @@ -41,6 +43,8 @@ uint32_t dolphin_state_xp_to_levelup(int icounter); uint32_t dolphin_state_xp_above_last_levelup(int icounter); +const int* dolphin_get_levels(); + bool dolphin_state_is_levelup(int icounter); void dolphin_state_increase_level(DolphinState* dolphin_state); diff --git a/applications/services/power/power_service/power.c b/applications/services/power/power_service/power.c index 76be018063..f0f7735fb8 100644 --- a/applications/services/power/power_service/power.c +++ b/applications/services/power/power_service/power.c @@ -1,14 +1,17 @@ #include "power_i.h" -#include "desktop/desktop_settings.h" #include #include +#include "../../../settings/xtreme_settings/xtreme_settings.h" #define POWER_OFF_TIMEOUT 90 void power_draw_battery_callback(Canvas* canvas, void* context) { furi_assert(context); Power* power = context; + BatteryStyle battery_style = XTREME_SETTINGS()->battery_style; + if(battery_style == BatteryStyleOff) return; + canvas_draw_icon(canvas, 0, 0, &I_Battery_25x8); canvas_set_color(canvas, ColorWhite); canvas_draw_box(canvas, -1, 0, 1, 8); @@ -21,8 +24,9 @@ void power_draw_battery_callback(Canvas* canvas, void* context) { if(power->info.gauge_is_ok) { char batteryPercentile[4]; snprintf(batteryPercentile, sizeof(batteryPercentile), "%d", power->info.charge); - if((power->displayBatteryPercentage == DISPLAY_BATTERY_PERCENT) && - (power->state != + + if((battery_style == BatteryStylePercent) && + (power->state != PowerStateCharging)) { //if display battery percentage, black background white text canvas_set_font(canvas, FontBatteryPercent); canvas_set_color(canvas, ColorBlack); @@ -30,14 +34,14 @@ void power_draw_battery_callback(Canvas* canvas, void* context) { canvas_set_color(canvas, ColorWhite); canvas_draw_str_aligned(canvas, 11, 4, AlignCenter, AlignCenter, batteryPercentile); } else if( - (power->displayBatteryPercentage == DISPLAY_BATTERY_INVERTED_PERCENT) && + (battery_style == BatteryStyleInvertedPercent) && (power->state != - PowerStateCharging)) { //if display inverted percentage, white background black text + PowerStateCharging)) { //if display inverted percentage, white background black text canvas_set_font(canvas, FontBatteryPercent); canvas_set_color(canvas, ColorBlack); canvas_draw_str_aligned(canvas, 11, 4, AlignCenter, AlignCenter, batteryPercentile); } else if( - (power->displayBatteryPercentage == DISPLAY_BATTERY_RETRO_3) && + (battery_style == BatteryStyleRetro3) && (power->state != PowerStateCharging)) { //Retro style segmented display, 3 parts if(power->info.charge > 25) { canvas_draw_box(canvas, 2, 2, 6, 4); @@ -49,7 +53,7 @@ void power_draw_battery_callback(Canvas* canvas, void* context) { canvas_draw_box(canvas, 16, 2, 6, 4); } } else if( - (power->displayBatteryPercentage == DISPLAY_BATTERY_RETRO_5) && + (battery_style == BatteryStyleRetro5) && (power->state != PowerStateCharging)) { //Retro style segmented display, 5 parts if(power->info.charge > 10) { canvas_draw_box(canvas, 2, 2, 3, 4); @@ -67,10 +71,10 @@ void power_draw_battery_callback(Canvas* canvas, void* context) { canvas_draw_box(canvas, 18, 2, 3, 4); } } else if( - (power->displayBatteryPercentage == DISPLAY_BATTERY_BAR_PERCENT) && + (battery_style == BatteryStyleBarPercent) && (power->state != PowerStateCharging) && // Default bar display with percentage (power->info.voltage_battery_charging >= - 4.2)) { // not looking nice with low voltage indicator + 4.2)) { // not looking nice with low voltage indicator canvas_set_font(canvas, FontBatteryPercent); // align charge dispaly value with digits to draw @@ -141,8 +145,8 @@ void power_draw_battery_callback(Canvas* canvas, void* context) { if(power->state == PowerStateCharging) { canvas_set_bitmap_mode(canvas, 1); // TODO: replace -1 magic for uint8_t with re-framing - if(power->displayBatteryPercentage == DISPLAY_BATTERY_PERCENT || - power->displayBatteryPercentage == DISPLAY_BATTERY_BAR_PERCENT) { + if(battery_style == BatteryStylePercent || + battery_style == BatteryStyleBarPercent) { canvas_set_color(canvas, ColorBlack); canvas_draw_box(canvas, 1, 1, 22, 6); canvas_draw_icon(canvas, 2, -1, &I_Charging_lightning_9x10); @@ -151,7 +155,7 @@ void power_draw_battery_callback(Canvas* canvas, void* context) { canvas_set_font(canvas, FontBatteryPercent); canvas_draw_str_aligned( canvas, 16, 4, AlignCenter, AlignCenter, batteryPercentile); - } else if(power->displayBatteryPercentage == DISPLAY_BATTERY_INVERTED_PERCENT) { + } else if(battery_style == BatteryStyleInvertedPercent) { canvas_set_color(canvas, ColorWhite); canvas_draw_box(canvas, 1, 1, 22, 6); canvas_draw_icon(canvas, 2, -1, &I_Charging_lightning_9x10); @@ -460,11 +464,6 @@ int32_t power_srv(void* p) { power_update_info(power); furi_record_create(RECORD_POWER, power); - DesktopSettings* settings = malloc(sizeof(DesktopSettings)); - DESKTOP_SETTINGS_LOAD(settings); - power->displayBatteryPercentage = settings->displayBatteryPercentage; - free(settings); - while(1) { // Update data from gauge and charger bool need_refresh = power_update_info(power); @@ -479,13 +478,7 @@ int32_t power_srv(void* p) { power_check_battery_level_change(power); // Update battery view port - if(need_refresh) { - DesktopSettings* settings = malloc(sizeof(DesktopSettings)); - DESKTOP_SETTINGS_LOAD(settings); - power->displayBatteryPercentage = settings->displayBatteryPercentage; - free(settings); - view_port_update(power->battery_view_port); - } + if(need_refresh) view_port_update(power->battery_view_port); // Check OTG status and disable it in case of fault if(furi_hal_power_is_otg_enabled()) { diff --git a/applications/services/power/power_service/power.h b/applications/services/power/power_service/power.h index 6469bc4222..58c85a9a97 100644 --- a/applications/services/power/power_service/power.h +++ b/applications/services/power/power_service/power.h @@ -25,6 +25,16 @@ typedef enum { PowerEventTypeBatteryLevelChanged, } PowerEventType; +typedef enum { + BatteryStyleOff = 1, + BatteryStyleBar = 2, + BatteryStylePercent = 3, + BatteryStyleInvertedPercent = 4, + BatteryStyleRetro3 = 5, + BatteryStyleRetro5 = 6, + BatteryStyleBarPercent = 0, +} BatteryStyle; + typedef union { uint8_t battery_level; } PowerEventData; diff --git a/applications/services/power/power_service/power_i.h b/applications/services/power/power_service/power_i.h index 9c027e1ceb..7cb7561758 100644 --- a/applications/services/power/power_service/power_i.h +++ b/applications/services/power/power_service/power_i.h @@ -44,7 +44,6 @@ struct Power { bool battery_low; bool show_low_bat_level_message; - uint8_t displayBatteryPercentage; uint8_t battery_level; uint8_t power_off_timeout; diff --git a/applications/settings/about/about.c b/applications/settings/about/about.c index 17c734a208..42712bc9c5 100644 --- a/applications/settings/about/about.c +++ b/applications/settings/about/about.c @@ -3,10 +3,17 @@ #include #include #include +#include #include #include #include #include +#include + +int screen_index; + +#define LOW_CHARGE_THRESHOLD 10 +#define HIGH_DRAIN_CURRENT_THRESHOLD 100 typedef DialogMessageButton (*AboutDialogScreen)(DialogsApp* dialogs, DialogMessage* message); @@ -151,6 +158,135 @@ static DialogMessageButton fw_version_screen(DialogsApp* dialogs, DialogMessage* return result; } +static void draw_stat(Canvas* canvas, int x, int y, const Icon* icon, char* val) { + canvas_draw_frame(canvas, x - 7, y + 7, 30, 13); + canvas_draw_icon(canvas, x, y, icon); + canvas_set_color(canvas, ColorWhite); + canvas_draw_box(canvas, x - 4, y + 16, 24, 6); + canvas_set_color(canvas, ColorBlack); + canvas_draw_str_aligned(canvas, x + 8, y + 22, AlignCenter, AlignBottom, val); +}; + +static void draw_battery(Canvas* canvas, PowerInfo* info, int x, int y) { + char header[20] = {}; + char value[20] = {}; + + int32_t drain_current = info->current_gauge * (-1000); + uint32_t charge_current = info->current_gauge * 1000; + + // Draw battery + canvas_draw_icon(canvas, x, y, &I_BatteryBody_52x28); + if(charge_current > 0) { + canvas_draw_icon(canvas, x + 16, y + 7, &I_FaceCharging_29x14); + } else if(drain_current > HIGH_DRAIN_CURRENT_THRESHOLD) { + canvas_draw_icon(canvas, x + 16, y + 7, &I_FaceConfused_29x14); + } else if(info->charge < LOW_CHARGE_THRESHOLD) { + canvas_draw_icon(canvas, x + 16, y + 7, &I_FaceNopower_29x14); + } else { + canvas_draw_icon(canvas, x + 16, y + 7, &I_FaceNormal_29x14); + } + + // Draw bubble + elements_bubble(canvas, x + 53, y + 0, 71, 28); + + // Set text + if(charge_current > 0) { + snprintf(header, sizeof(header), "%s", "Charging at"); + snprintf( + value, + sizeof(value), + "%lu.%luV %lumA", + (uint32_t)(info->voltage_vbus), + (uint32_t)(info->voltage_vbus * 10) % 10, + charge_current); + } else if(drain_current > 0) { + snprintf(header, sizeof(header), "%s", "Consumption is"); + snprintf( + value, + sizeof(value), + "%ld %s", + drain_current, + drain_current > HIGH_DRAIN_CURRENT_THRESHOLD ? "mA!" : "mA"); + } else if(drain_current != 0) { + snprintf(header, 20, "..."); + } else if(info->voltage_battery_charging < 4.2) { + // Non-default battery charging limit, mention it + snprintf(header, sizeof(header), "Limited to"); + snprintf( + value, + sizeof(value), + "%lu.%luV", + (uint32_t)(info->voltage_battery_charging), + (uint32_t)(info->voltage_battery_charging * 10) % 10); + } else { + snprintf(header, sizeof(header), "Charged!"); + } + + if (!strcmp(value, "")) { + canvas_draw_str_aligned(canvas, x + 92, y + 14, AlignCenter, AlignCenter, header); + } else if (!strcmp(header, "")) { + canvas_draw_str_aligned(canvas, x + 92, y + 14, AlignCenter, AlignCenter, value); + } else { + canvas_draw_str_aligned(canvas, x + 92, y + 9, AlignCenter, AlignCenter, header); + canvas_draw_str_aligned(canvas, x + 92, y + 19, AlignCenter, AlignCenter, value); + } +}; + +static void battery_info_draw_callback(Canvas* canvas, void* context) { + furi_assert(context); + PowerInfo* info = context; + + canvas_clear(canvas); + canvas_set_color(canvas, ColorBlack); + draw_battery(canvas, info, 0, 0); + + char batt_level[10]; + char temperature[10]; + char voltage[10]; + char health[10]; + + snprintf(batt_level, sizeof(batt_level), "%lu%%", (uint32_t)info->charge); + snprintf(temperature, sizeof(temperature), "%lu C", (uint32_t)info->temperature_gauge); + snprintf( + voltage, + sizeof(voltage), + "%lu.%01lu V", + (uint32_t)info->voltage_gauge, + (uint32_t)(info->voltage_gauge * 10) % 10UL); + snprintf(health, sizeof(health), "%d%%", info->health); + + draw_stat(canvas, 8, 28, &I_Battery_16x16, batt_level); + draw_stat(canvas, 40, 28, &I_Temperature_16x16, temperature); + draw_stat(canvas, 72, 28, &I_Voltage_16x16, voltage); + draw_stat(canvas, 104, 28, &I_Health_16x16, health); + + elements_button_left(canvas, "Back"); + elements_button_right(canvas, "Next"); +} + +static bool battery_info_input_callback(InputEvent* event, void* context) { + FuriSemaphore* semaphore = context; + + bool consumed = false; + if(event->type == InputTypeShort) { + if(event->key == InputKeyLeft) { + screen_index--; + consumed = true; + } else if(event->key == InputKeyRight) { + screen_index++; + consumed = true; + } else if(event->key == InputKeyBack) { + screen_index = -2; + consumed = true; + } + } + + if(consumed) { + furi_semaphore_release(semaphore); + } + return consumed; +} + const AboutDialogScreen about_screens[] = { product_screen, hw_version_screen, @@ -160,55 +296,81 @@ const AboutDialogScreen about_screens[] = { compliance_screen, address_screen}; -const size_t about_screens_count = sizeof(about_screens) / sizeof(AboutDialogScreen); +const int about_screens_count = sizeof(about_screens) / sizeof(AboutDialogScreen); + int32_t about_settings_app(void* p) { - UNUSED(p); - DialogsApp* dialogs = furi_record_open(RECORD_DIALOGS); - DialogMessage* message = dialog_message_alloc(); + bool battery_info = false; + if(p && strlen(p) && !strcmp(p, "batt")) { + battery_info = true; + } Gui* gui = furi_record_open(RECORD_GUI); ViewDispatcher* view_dispatcher = view_dispatcher_alloc(); - EmptyScreen* empty_screen = empty_screen_alloc(); - const uint32_t empty_screen_index = 0; + const uint32_t battery_info_index = 0; + const uint32_t empty_screen_index = 1; - size_t screen_index = 0; + FuriSemaphore* semaphore = furi_semaphore_alloc(1, 0); + Power* power = furi_record_open(RECORD_POWER); + View* battery_view = view_alloc(); + view_set_context(battery_view, semaphore); + view_set_input_callback(battery_view, battery_info_input_callback); + view_allocate_model(battery_view, ViewModelTypeLocking, sizeof(PowerInfo)); + view_set_draw_callback(battery_view, battery_info_draw_callback); + + DialogsApp* dialogs = furi_record_open(RECORD_DIALOGS); + DialogMessage* message = dialog_message_alloc(); + EmptyScreen* empty_screen = empty_screen_alloc(); DialogMessageButton screen_result; // draw empty screen to prevent menu flickering + view_dispatcher_add_view( + view_dispatcher, battery_info_index, battery_view); view_dispatcher_add_view( view_dispatcher, empty_screen_index, empty_screen_get_view(empty_screen)); view_dispatcher_attach_to_gui(view_dispatcher, gui, ViewDispatcherTypeFullscreen); - view_dispatcher_switch_to_view(view_dispatcher, empty_screen_index); - while(1) { - if(screen_index >= about_screens_count - 1) { - dialog_message_set_buttons(message, "Back", NULL, NULL); - } else { - dialog_message_set_buttons(message, "Back", NULL, "Next"); - } + screen_index = -1 + !battery_info; + while(screen_index > -2) { - screen_result = about_screens[screen_index](dialogs, message); - - if(screen_result == DialogMessageButtonLeft) { - if(screen_index <= 0) { + if (screen_index == -1) { + if (!battery_info) { break; + } + with_view_model( + battery_view, + PowerInfo * model, + { power_get_info(power, model); }, + true); + view_dispatcher_switch_to_view(view_dispatcher, battery_info_index); + furi_semaphore_acquire(semaphore, 2000); + } else { + view_dispatcher_switch_to_view(view_dispatcher, empty_screen_index); + if(screen_index >= about_screens_count - 1) { + dialog_message_set_buttons(message, "Back", NULL, NULL); } else { - screen_index--; + dialog_message_set_buttons(message, "Back", NULL, "Next"); } - } else if(screen_result == DialogMessageButtonRight) { - if(screen_index < about_screens_count) { + screen_result = about_screens[screen_index](dialogs, message); + if(screen_result == DialogMessageButtonLeft) { + screen_index--; + } else if(screen_result == DialogMessageButtonRight) { screen_index++; + } else if(screen_result == DialogMessageButtonBack) { + screen_index = -2; } - } else if(screen_result == DialogMessageButtonBack) { - break; } + } dialog_message_free(message); furi_record_close(RECORD_DIALOGS); + furi_record_close(RECORD_POWER); + furi_semaphore_free(semaphore); view_dispatcher_remove_view(view_dispatcher, empty_screen_index); + view_dispatcher_remove_view(view_dispatcher, battery_info_index); + view_free(battery_view); view_dispatcher_free(view_dispatcher); empty_screen_free(empty_screen); furi_record_close(RECORD_GUI); diff --git a/applications/settings/application.fam b/applications/settings/application.fam index cc4b9703dc..0c4a98835e 100644 --- a/applications/settings/application.fam +++ b/applications/settings/application.fam @@ -5,6 +5,7 @@ App( provides=[ "passport", "system_settings", + "xtreme_settings", "about", ], ) diff --git a/applications/settings/bt_settings_app/scenes/bt_settings_scene_forget_dev_success.c b/applications/settings/bt_settings_app/scenes/bt_settings_scene_forget_dev_success.c index 79651a9766..4112d94d9b 100644 --- a/applications/settings/bt_settings_app/scenes/bt_settings_scene_forget_dev_success.c +++ b/applications/settings/bt_settings_app/scenes/bt_settings_scene_forget_dev_success.c @@ -1,6 +1,6 @@ #include "../bt_settings_app.h" #include "furi_hal_bt.h" -#include "../../desktop_settings/desktop_settings_app.h" +#include "../../xtreme_settings/xtreme_assets.h" void bt_settings_app_scene_forget_dev_success_popup_callback(void* context) { BtSettingsApp* app = context; @@ -10,21 +10,14 @@ void bt_settings_app_scene_forget_dev_success_popup_callback(void* context) { void bt_settings_scene_forget_dev_success_on_enter(void* context) { BtSettingsApp* app = context; Popup* popup = app->popup; - DesktopSettings* settings = malloc(sizeof(DesktopSettings)); - DESKTOP_SETTINGS_LOAD(settings); - if(settings->sfw_mode) { - popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59_sfw); - } else { - popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59); - } + popup_set_icon(popup, 32, 5, XTREME_ASSETS()->I_DolphinNice_96x59); popup_set_header(popup, "Done", 14, 15, AlignLeft, AlignTop); popup_set_timeout(popup, 1500); popup_set_context(popup, app); popup_set_callback(popup, bt_settings_app_scene_forget_dev_success_popup_callback); popup_enable_timeout(popup); view_dispatcher_switch_to_view(app->view_dispatcher, BtSettingsAppViewPopup); - free(settings); } bool bt_settings_scene_forget_dev_success_on_event(void* context, SceneManagerEvent event) { diff --git a/applications/settings/desktop_settings/scenes/desktop_settings_scene_pin_disable.c b/applications/settings/desktop_settings/scenes/desktop_settings_scene_pin_disable.c index 4b183251bb..cdafbb8280 100644 --- a/applications/settings/desktop_settings/scenes/desktop_settings_scene_pin_disable.c +++ b/applications/settings/desktop_settings/scenes/desktop_settings_scene_pin_disable.c @@ -6,6 +6,7 @@ #include "../desktop_settings_app.h" #include #include "desktop_settings_scene.h" +#include "../../xtreme_settings/xtreme_assets.h" #define SCENE_EVENT_EXIT (0U) @@ -21,21 +22,14 @@ void desktop_settings_scene_pin_disable_on_enter(void* context) { app->settings.pin_code.length = 0; memset(app->settings.pin_code.data, '0', sizeof(app->settings.pin_code.data)); DESKTOP_SETTINGS_SAVE(&app->settings); - DesktopSettings* settings = malloc(sizeof(DesktopSettings)); - DESKTOP_SETTINGS_LOAD(settings); popup_set_context(app->popup, app); popup_set_callback(app->popup, pin_disable_back_callback); - if(settings->sfw_mode) { - popup_set_icon(app->popup, 0, 2, &I_DolphinMafia_115x62_sfw); - } else { - popup_set_icon(app->popup, 0, 2, &I_DolphinMafia_115x62); - } + popup_set_icon(app->popup, 0, 2, XTREME_ASSETS()->I_DolphinMafia_115x62); popup_set_header(app->popup, "PIN\nDeleted!", 95, 9, AlignCenter, AlignCenter); popup_set_timeout(app->popup, 1500); popup_enable_timeout(app->popup); view_dispatcher_switch_to_view(app->view_dispatcher, DesktopSettingsAppViewIdPopup); - free(settings); } bool desktop_settings_scene_pin_disable_on_event(void* context, SceneManagerEvent event) { diff --git a/applications/settings/desktop_settings/scenes/desktop_settings_scene_start.c b/applications/settings/desktop_settings/scenes/desktop_settings_scene_start.c index b97c2a4a28..33b7fd0458 100644 --- a/applications/settings/desktop_settings/scenes/desktop_settings_scene_start.c +++ b/applications/settings/desktop_settings/scenes/desktop_settings_scene_start.c @@ -26,39 +26,6 @@ const char* const auto_lock_delay_text[AUTO_LOCK_DELAY_COUNT] = { const uint32_t auto_lock_delay_value[AUTO_LOCK_DELAY_COUNT] = {0, 10000, 15000, 30000, 60000, 90000, 120000, 300000, 600000}; -#define BATTERY_VIEW_COUNT 6 -const char* const battery_view_count_text[BATTERY_VIEW_COUNT] = - {"Bar", "%", "Inv. %", "Retro 3", "Retro 5", "Bar %"}; -const uint32_t displayBatteryPercentage_value[BATTERY_VIEW_COUNT] = { - DISPLAY_BATTERY_BAR, - DISPLAY_BATTERY_PERCENT, - DISPLAY_BATTERY_INVERTED_PERCENT, - DISPLAY_BATTERY_RETRO_3, - DISPLAY_BATTERY_RETRO_5, - DISPLAY_BATTERY_BAR_PERCENT}; - -uint8_t origBattDisp_value = 0; - -#define CYCLE_ANIMATION_COUNT 13 -const char* const cycle_animation_text[CYCLE_ANIMATION_COUNT] = { - "OFF", - "Manifest", - "30 S", - "1 M", - "5 M", - "10 M", - "15 M", - "30 M", - "1 H", - "2 H", - "6 H", - "12 H", - "24 H", -}; -// Values are offset by 1 so that 0 is not a valid value and desktop.c can detect this to set a default value (3601 / 1 H) -const int32_t cycle_animation_value[CYCLE_ANIMATION_COUNT] = - {1, -1, 31, 61, 301, 601, 901, 1801, 3601, 7201, 21601, 43201, 86401}; - static void desktop_settings_scene_start_var_list_enter_callback(void* context, uint32_t index) { DesktopSettingsApp* app = context; view_dispatcher_send_custom_event(app->view_dispatcher, index); @@ -72,26 +39,9 @@ static void desktop_settings_scene_start_auto_lock_delay_changed(VariableItem* i app->settings.auto_lock_delay_ms = auto_lock_delay_value[index]; } -static void desktop_settings_scene_start_battery_view_changed(VariableItem* item) { - DesktopSettingsApp* app = variable_item_get_context(item); - uint8_t index = variable_item_get_current_value_index(item); - - variable_item_set_current_value_text(item, battery_view_count_text[index]); - app->settings.displayBatteryPercentage = index; -} - -static void desktop_settings_scene_start_cycle_animation_changed(VariableItem* item) { - DesktopSettingsApp* app = variable_item_get_context(item); - uint8_t index = variable_item_get_current_value_index(item); - - variable_item_set_current_value_text(item, cycle_animation_text[index]); - app->settings.cycle_animation_s = cycle_animation_value[index]; -} - void desktop_settings_scene_start_on_enter(void* context) { DesktopSettingsApp* app = context; VariableItemList* variable_item_list = app->variable_item_list; - origBattDisp_value = app->settings.displayBatteryPercentage; VariableItem* item; uint8_t value_index; @@ -116,32 +66,6 @@ void desktop_settings_scene_start_on_enter(void* context) { variable_item_set_current_value_index(item, value_index); variable_item_set_current_value_text(item, auto_lock_delay_text[value_index]); - item = variable_item_list_add( - variable_item_list, - "Battery View", - BATTERY_VIEW_COUNT, - desktop_settings_scene_start_battery_view_changed, - app); - - value_index = value_index_uint32( - app->settings.displayBatteryPercentage, - displayBatteryPercentage_value, - BATTERY_VIEW_COUNT); - variable_item_set_current_value_index(item, value_index); - variable_item_set_current_value_text(item, battery_view_count_text[value_index]); - - item = variable_item_list_add( - variable_item_list, - "Cycle Animation", - CYCLE_ANIMATION_COUNT, - desktop_settings_scene_start_cycle_animation_changed, - app); - - value_index = value_index_int32( - app->settings.cycle_animation_s, cycle_animation_value, CYCLE_ANIMATION_COUNT); - variable_item_set_current_value_index(item, value_index); - variable_item_set_current_value_text(item, cycle_animation_text[value_index]); - variable_item_list_set_enter_callback( variable_item_list, desktop_settings_scene_start_var_list_enter_callback, app); view_dispatcher_switch_to_view(app->view_dispatcher, DesktopSettingsAppViewVarItemList); @@ -187,8 +111,4 @@ void desktop_settings_scene_start_on_exit(void* context) { DesktopSettingsApp* app = context; variable_item_list_reset(app->variable_item_list); DESKTOP_SETTINGS_SAVE(&app->settings); - - if(app->settings.displayBatteryPercentage != origBattDisp_value) { - furi_hal_power_reset(); - } } diff --git a/applications/settings/dolphin_passport/passport.c b/applications/settings/dolphin_passport/passport.c index b6c94d2c15..3bea705acf 100644 --- a/applications/settings/dolphin_passport/passport.c +++ b/applications/settings/dolphin_passport/passport.c @@ -6,36 +6,9 @@ #include #include #include "dolphin/dolphin.h" -#include "../desktop_settings/desktop_settings_app.h" +#include "../xtreme_settings/xtreme_assets.h" #include "math.h" -#define MOODS_TOTAL 3 -#define BUTTHURT_MAX 3 - -static const Icon* const portrait_happy_sfw[BUTTHURT_MAX] = { - &I_passport_happy1_46x49_sfw, - &I_passport_happy2_46x49_sfw, - &I_passport_happy3_46x49_sfw}; -static const Icon* const portrait_ok_sfw[BUTTHURT_MAX] = { - &I_passport_okay1_46x49_sfw, - &I_passport_okay2_46x49_sfw, - &I_passport_okay3_46x49_sfw}; -static const Icon* const portrait_bad_sfw[BUTTHURT_MAX] = { - &I_passport_bad1_46x49_sfw, - &I_passport_bad2_46x49_sfw, - &I_passport_bad3_46x49_sfw}; - -static const Icon* const portrait_happy[BUTTHURT_MAX] = {&I_flipper}; -static const Icon* const portrait_ok[BUTTHURT_MAX] = {&I_flipper}; -static const Icon* const portrait_bad[BUTTHURT_MAX] = {&I_flipper}; - -static const Icon* const* portraits_sfw[MOODS_TOTAL] = { - portrait_happy_sfw, - portrait_ok_sfw, - portrait_bad_sfw}; -static const Icon* const* portraits[MOODS_TOTAL] = {portrait_happy, portrait_ok, portrait_bad}; -// static const Icon* const* portraits[MOODS_TOTAL] = {portrait_happy}; - typedef struct { FuriSemaphore* semaphore; DolphinStats* stats; @@ -60,35 +33,34 @@ static void render_callback(Canvas* canvas, void* _ctx) { PassportContext* ctx = _ctx; DolphinStats* stats = ctx->stats; - DesktopSettings* settings = malloc(sizeof(DesktopSettings)); - DESKTOP_SETTINGS_LOAD(settings); + XtremeAssets* xtreme_assets = XTREME_ASSETS(); char level_str[20]; char xp_str[12]; - char mood_str[32]; - uint8_t mood = 0; + const char* mood_str = NULL; + const Icon* portrait = NULL; - if(settings->sfw_mode) { + if(XTREME_SETTINGS()->nsfw_mode) { if(stats->butthurt <= 4) { - mood = 0; - snprintf(mood_str, 20, "Mood: Happy"); + portrait = xtreme_assets->I_passport_happy_46x49; + mood_str = "Status: Wet"; } else if(stats->butthurt <= 9) { - mood = 1; - snprintf(mood_str, 20, "Mood: Okay"); + portrait = xtreme_assets->I_passport_okay_46x49; + mood_str = "Status: Horny"; } else { - mood = 2; - snprintf(mood_str, 20, "Mood: Angry"); + portrait = xtreme_assets->I_passport_bad_46x49; + mood_str = "Status: Desperate"; } } else { if(stats->butthurt <= 4) { - mood = 0; - snprintf(mood_str, 20, "Status: Wet"); + portrait = xtreme_assets->I_passport_happy_46x49; + mood_str = "Mood: Happy"; } else if(stats->butthurt <= 9) { - mood = 1; - snprintf(mood_str, 20, "Status: Horny"); + portrait = xtreme_assets->I_passport_okay_46x49; + mood_str = "Mood: Okay"; } else { - mood = 2; - snprintf(mood_str, 20, "Status: Desperate"); + portrait = xtreme_assets->I_passport_bad_46x49; + mood_str = "Mood: Angry"; } } uint32_t xp_progress = 0; @@ -102,31 +74,26 @@ static void render_callback(Canvas* canvas, void* _ctx) { } uint32_t xp_have = xp_levelup - xp_need; - if(stats->level == 30) { + if(stats->level == DOLPHIN_LEVEL_COUNT + 1) { xp_progress = 0; } else { xp_progress = xp_need * 64 / xp_levelup; } // multipass - if(settings->sfw_mode) { - canvas_draw_icon(canvas, 0, 0, &I_passport_DB_sfw); - } else { - canvas_draw_icon(canvas, 0, 0, &I_passport_DB); - } + canvas_draw_icon(canvas, 0, 0, xtreme_assets->I_passport_DB); // portrait - furi_assert((stats->level > 0) && (stats->level <= 30)); - uint16_t tmpLvl = 0; - if(settings->sfw_mode) { - canvas_draw_icon(canvas, 11, 2, portraits_sfw[mood][tmpLvl]); - } else { - canvas_draw_icon(canvas, 11, 2, portraits[mood][tmpLvl]); - } + furi_assert((stats->level > 0) && (stats->level <= DOLPHIN_LEVEL_COUNT + 1)); + canvas_draw_icon(canvas, 11, 2, portrait); const char* my_name = furi_hal_version_get_name_ptr(); snprintf(level_str, 12, "Level: %hu", stats->level); - snprintf(xp_str, 12, "%lu/%lu", xp_have, xp_levelup); + if(stats->level == DOLPHIN_LEVEL_COUNT + 1) { + snprintf(xp_str, 12, "Max Level!"); + } else { + snprintf(xp_str, 12, "%lu/%lu", xp_have, xp_levelup); + } canvas_set_font(canvas, FontSecondary); canvas_draw_str(canvas, 58, 10, my_name ? my_name : "Unknown"); canvas_draw_str(canvas, 58, 22, mood_str); @@ -138,14 +105,12 @@ static void render_callback(Canvas* canvas, void* _ctx) { canvas_set_font(canvas, FontSecondary); canvas_set_color(canvas, ColorWhite); - canvas_draw_box(canvas, 123 - xp_progress, 45, xp_progress + 1, 5); + canvas_draw_box(canvas, 123 - xp_progress, 45, xp_progress + (xp_progress > 0), 5); canvas_set_color(canvas, ColorBlack); canvas_draw_icon(canvas, 52, 51, &I_Ok_btn_9x9); canvas_draw_str( canvas, ctx->progress_total ? 37 : 36, 59, ctx->progress_total ? "Lvl" : "Tot"); - - free(settings); } int32_t passport_app(void* p) { diff --git a/applications/settings/power_settings_app/scenes/power_settings_scene_power_off.c b/applications/settings/power_settings_app/scenes/power_settings_scene_power_off.c index 43d429692c..ecab8c3332 100644 --- a/applications/settings/power_settings_app/scenes/power_settings_scene_power_off.c +++ b/applications/settings/power_settings_app/scenes/power_settings_scene_power_off.c @@ -1,5 +1,5 @@ #include "../power_settings_app.h" -#include "../../desktop_settings/desktop_settings_app.h" +#include "../../xtreme_settings/xtreme_assets.h" void power_settings_scene_power_off_dialog_callback(DialogExResult result, void* context) { furi_assert(context); @@ -11,26 +11,21 @@ void power_settings_scene_power_off_on_enter(void* context) { PowerSettingsApp* app = context; DialogEx* dialog = app->dialog; - DesktopSettings* settings = malloc(sizeof(DesktopSettings)); - DESKTOP_SETTINGS_LOAD(settings); - dialog_ex_set_header(dialog, "Turn Off Device?", 64, 2, AlignCenter, AlignTop); - if(settings->sfw_mode) { + if(XTREME_SETTINGS()->nsfw_mode) { dialog_ex_set_text( - dialog, " I will be\nwaiting for\n you here", 78, 16, AlignLeft, AlignTop); - dialog_ex_set_icon(dialog, 21, 13, &I_Cry_dolph_55x52_sfw); + dialog, " I will be\nwaiting for\n you master", 78, 16, AlignLeft, AlignTop); } else { dialog_ex_set_text( - dialog, " I will be\nwaiting for\n you master", 78, 16, AlignLeft, AlignTop); - dialog_ex_set_icon(dialog, 21, 13, &I_Cry_dolph_55x52); + dialog, " I will be\nwaiting for\n you here", 78, 16, AlignLeft, AlignTop); } + dialog_ex_set_icon(dialog, 21, 13, XTREME_ASSETS()->I_Cry_dolph_55x52); dialog_ex_set_left_button_text(dialog, "Back"); dialog_ex_set_right_button_text(dialog, "OFF"); dialog_ex_set_result_callback(dialog, power_settings_scene_power_off_dialog_callback); dialog_ex_set_context(dialog, app); view_dispatcher_switch_to_view(app->view_dispatcher, PowerSettingsAppViewDialog); - free(settings); } bool power_settings_scene_power_off_on_event(void* context, SceneManagerEvent event) { diff --git a/applications/settings/storage_settings/scenes/storage_settings_scene_unmounted.c b/applications/settings/storage_settings/scenes/storage_settings_scene_unmounted.c index 4d8f81f9ea..455cbaa787 100644 --- a/applications/settings/storage_settings/scenes/storage_settings_scene_unmounted.c +++ b/applications/settings/storage_settings/scenes/storage_settings_scene_unmounted.c @@ -1,5 +1,5 @@ #include "../storage_settings.h" -#include "../../desktop_settings/desktop_settings_app.h" +#include "../../xtreme_settings/xtreme_assets.h" static void storage_settings_scene_unmounted_dialog_callback(DialogExResult result, void* context) { @@ -12,15 +12,9 @@ void storage_settings_scene_unmounted_on_enter(void* context) { StorageSettings* app = context; FS_Error error = storage_sd_unmount(app->fs_api); DialogEx* dialog_ex = app->dialog_ex; - DesktopSettings* settings = malloc(sizeof(DesktopSettings)); - DESKTOP_SETTINGS_LOAD(settings); dialog_ex_set_center_button_text(dialog_ex, "OK"); - if(settings->sfw_mode) { - dialog_ex_set_icon(dialog_ex, 72, 17, &I_DolphinCommon_56x48_sfw); - } else { - dialog_ex_set_icon(dialog_ex, 72, 17, &I_DolphinCommon_56x48); - } + dialog_ex_set_icon(dialog_ex, 72, 17, XTREME_ASSETS()->I_DolphinCommon_56x48); if(error == FSE_OK) { dialog_ex_set_header(dialog_ex, "SD Card Unmounted", 64, 3, AlignCenter, AlignTop); @@ -36,7 +30,6 @@ void storage_settings_scene_unmounted_on_enter(void* context) { dialog_ex_set_result_callback(dialog_ex, storage_settings_scene_unmounted_dialog_callback); view_dispatcher_switch_to_view(app->view_dispatcher, StorageSettingsViewDialogEx); - free(settings); } bool storage_settings_scene_unmounted_on_event(void* context, SceneManagerEvent event) { diff --git a/applications/settings/xtreme_settings/application.fam b/applications/settings/xtreme_settings/application.fam new file mode 100644 index 0000000000..54dd95af30 --- /dev/null +++ b/applications/settings/xtreme_settings/application.fam @@ -0,0 +1,11 @@ +App( + appid="xtreme_settings", + name="Xtreme FW", + apptype=FlipperAppType.SETTINGS, + entry_point="xtreme_settings_app", + stack_size=2 * 1024, + requires=[ + "gui", + ], + order=90, +) diff --git a/applications/settings/xtreme_settings/scenes/xtreme_settings_scene.c b/applications/settings/xtreme_settings/scenes/xtreme_settings_scene.c new file mode 100644 index 0000000000..3d97ed9794 --- /dev/null +++ b/applications/settings/xtreme_settings/scenes/xtreme_settings_scene.c @@ -0,0 +1,30 @@ +#include "xtreme_settings_scene.h" + +// Generate scene on_enter handlers array +#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_enter, +void (*const xtreme_settings_on_enter_handlers[])(void*) = { +#include "xtreme_settings_scene_config.h" +}; +#undef ADD_SCENE + +// Generate scene on_event handlers array +#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_event, +bool (*const xtreme_settings_on_event_handlers[])(void* context, SceneManagerEvent event) = { +#include "xtreme_settings_scene_config.h" +}; +#undef ADD_SCENE + +// Generate scene on_exit handlers array +#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_exit, +void (*const xtreme_settings_on_exit_handlers[])(void* context) = { +#include "xtreme_settings_scene_config.h" +}; +#undef ADD_SCENE + +// Initialize scene handlers configuration structure +const SceneManagerHandlers xtreme_settings_scene_handlers = { + .on_enter_handlers = xtreme_settings_on_enter_handlers, + .on_event_handlers = xtreme_settings_on_event_handlers, + .on_exit_handlers = xtreme_settings_on_exit_handlers, + .scene_num = XtremeSettingsAppSceneNum, +}; diff --git a/applications/settings/xtreme_settings/scenes/xtreme_settings_scene.h b/applications/settings/xtreme_settings/scenes/xtreme_settings_scene.h new file mode 100644 index 0000000000..70abf4f779 --- /dev/null +++ b/applications/settings/xtreme_settings/scenes/xtreme_settings_scene.h @@ -0,0 +1,29 @@ +#pragma once + +#include + +// Generate scene id and total number +#define ADD_SCENE(prefix, name, id) XtremeSettingsAppScene##id, +typedef enum { +#include "xtreme_settings_scene_config.h" + XtremeSettingsAppSceneNum, +} XtremeSettingsAppScene; +#undef ADD_SCENE + +extern const SceneManagerHandlers xtreme_settings_scene_handlers; + +// Generate scene on_enter handlers declaration +#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_enter(void*); +#include "xtreme_settings_scene_config.h" +#undef ADD_SCENE + +// Generate scene on_event handlers declaration +#define ADD_SCENE(prefix, name, id) \ + bool prefix##_scene_##name##_on_event(void* context, SceneManagerEvent event); +#include "xtreme_settings_scene_config.h" +#undef ADD_SCENE + +// Generate scene on_exit handlers declaration +#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_exit(void* context); +#include "xtreme_settings_scene_config.h" +#undef ADD_SCENE diff --git a/applications/settings/xtreme_settings/scenes/xtreme_settings_scene_config.h b/applications/settings/xtreme_settings/scenes/xtreme_settings_scene_config.h new file mode 100644 index 0000000000..eddd4f82fa --- /dev/null +++ b/applications/settings/xtreme_settings/scenes/xtreme_settings_scene_config.h @@ -0,0 +1 @@ +ADD_SCENE(xtreme_settings, start, Start) diff --git a/applications/settings/xtreme_settings/scenes/xtreme_settings_scene_start.c b/applications/settings/xtreme_settings/scenes/xtreme_settings_scene_start.c new file mode 100644 index 0000000000..90bdde83f2 --- /dev/null +++ b/applications/settings/xtreme_settings/scenes/xtreme_settings_scene_start.c @@ -0,0 +1,256 @@ +#include "../xtreme_settings_app.h" +#include +#include +#include + +static void xtreme_settings_scene_start_base_graphics_changed(VariableItem* item) { + XtremeSettingsApp* app = variable_item_get_context(item); + bool value = variable_item_get_current_value_index(item); + variable_item_set_current_value_text(item, value ? "NSFW" : "SFW"); + XTREME_SETTINGS()->nsfw_mode = value; + app->settings_changed = true; + app->assets_changed = true; +} + +static void xtreme_settings_scene_start_asset_pack_changed(VariableItem* item) { + XtremeSettingsApp* app = variable_item_get_context(item); + uint8_t index = variable_item_get_current_value_index(item); + variable_item_set_current_value_text(item, index == 0 ? "OFF" : *asset_packs_get(app->asset_packs, index - 1)); + strlcpy(XTREME_SETTINGS()->asset_pack, index == 0 ? "" : *asset_packs_get(app->asset_packs, index - 1), MAX_PACK_NAME_LEN); + app->settings_changed = true; + app->assets_changed = true; +} + +const char* const anim_speed_names[] = + {"25%", "50%", "75%", "100%", "125%", "150%", "175%", "200%", "225%", "250%", "275%", "300%"}; +const int32_t anim_speed_values[COUNT_OF(anim_speed_names)] = + {25, 50, 75, 0, 125, 150, 175, 200, 225, 250, 275, 300}; +static void xtreme_settings_scene_start_anim_speed_changed(VariableItem* item) { + XtremeSettingsApp* app = variable_item_get_context(item); + uint8_t index = variable_item_get_current_value_index(item); + variable_item_set_current_value_text(item, anim_speed_names[index]); + XTREME_SETTINGS()->anim_speed = anim_speed_values[index]; + app->settings_changed = true; +} + +const char* const cycle_anims_names[] = + {"OFF", "Meta.txt", "30 S", "1 M", "5 M", "10 M", "15 M", "30 M", "1 H", "2 H", "6 H", "12 H", "24 H"}; +const int32_t cycle_anims_values[COUNT_OF(cycle_anims_names)] = + {-1, 0, 30, 60, 300, 600, 900, 1800, 3600, 7200, 21600, 43200, 86400}; +static void xtreme_settings_scene_start_cycle_anims_changed(VariableItem* item) { + XtremeSettingsApp* app = variable_item_get_context(item); + uint8_t index = variable_item_get_current_value_index(item); + variable_item_set_current_value_text(item, cycle_anims_names[index]); + XTREME_SETTINGS()->cycle_anims = cycle_anims_values[index]; + app->settings_changed = true; +} + +static void xtreme_settings_scene_start_unlock_anims_changed(VariableItem* item) { + XtremeSettingsApp* app = variable_item_get_context(item); + bool value = variable_item_get_current_value_index(item); + variable_item_set_current_value_text(item, value ? "ON" : "OFF"); + XTREME_SETTINGS()->unlock_anims = value; + app->settings_changed = true; +} + +const char* const battery_style_names[] = + {"OFF", "Bar", "%", "Inv. %", "Retro 3", "Retro 5", "Bar %"}; +const int32_t battery_style_values[COUNT_OF(battery_style_names)] = { + BatteryStyleOff, + BatteryStyleBar, + BatteryStylePercent, + BatteryStyleInvertedPercent, + BatteryStyleRetro3, + BatteryStyleRetro5, + BatteryStyleBarPercent +}; +static void xtreme_settings_scene_start_battery_style_changed(VariableItem* item) { + XtremeSettingsApp* app = variable_item_get_context(item); + uint8_t index = variable_item_get_current_value_index(item); + variable_item_set_current_value_text(item, battery_style_names[index]); + XTREME_SETTINGS()->battery_style = battery_style_values[index]; + app->settings_changed = true; +} + +static void xtreme_settings_scene_start_xp_level_changed(VariableItem* item) { + XtremeSettingsApp* app = variable_item_get_context(item); + app->dolphin_level = variable_item_get_current_value_index(item) + 1; + char level_str[4]; + snprintf(level_str, 4, "%i", app->dolphin_level); + variable_item_set_current_value_text(item, level_str); + app->level_changed = true; +} + +static void xtreme_settings_scene_start_subghz_extend_changed(VariableItem* item) { + XtremeSettingsApp* app = variable_item_get_context(item); + app->subghz_extend = variable_item_get_current_value_index(item); + variable_item_set_current_value_text(item, app->subghz_extend ? "ON" : "OFF"); + app->subghz_changed = true; +} + +static void xtreme_settings_scene_start_subghz_bypass_changed(VariableItem* item) { + XtremeSettingsApp* app = variable_item_get_context(item); + app->subghz_bypass = variable_item_get_current_value_index(item); + variable_item_set_current_value_text(item, app->subghz_bypass ? "ON" : "OFF"); + app->subghz_changed = true; +} + +void xtreme_settings_scene_start_on_enter(void* context) { + XtremeSettingsApp* app = context; + XtremeSettings* xtreme_settings = XTREME_SETTINGS(); + VariableItemList* var_item_list = app->var_item_list; + VariableItem* item; + uint8_t value_index; + + Dolphin* dolphin = furi_record_open(RECORD_DOLPHIN); + DolphinStats stats = dolphin_stats(dolphin); + furi_record_close(RECORD_DOLPHIN); + app->dolphin_level = stats.level; + + Storage* storage = furi_record_open(RECORD_STORAGE); + FlipperFormat* subghz_range = flipper_format_file_alloc(storage); + app->subghz_extend = false; + app->subghz_bypass = false; + if(flipper_format_file_open_existing(subghz_range, "/ext/subghz/assets/extend_range.txt")) { + flipper_format_read_bool(subghz_range, "use_ext_range_at_own_risk", &app->subghz_extend, 1); + flipper_format_read_bool(subghz_range, "ignore_default_tx_region", &app->subghz_bypass, 1); + } + flipper_format_free(subghz_range); + + uint current_pack = 0; + asset_packs_init(app->asset_packs); + File* folder = storage_file_alloc(storage); + FileInfo info; + char* name = malloc(MAX_PACK_NAME_LEN); + do { + if (!storage_dir_open(folder, PACKS_DIR)) break; + while(true) { + if (!storage_dir_read(folder, &info, name, MAX_PACK_NAME_LEN)) break; + if(info.flags & FSF_DIRECTORY) { + char* copy = malloc(MAX_PACK_NAME_LEN); + strlcpy(copy, name, MAX_PACK_NAME_LEN); + asset_packs_push_back(app->asset_packs, copy); + if (strcmp(name, xtreme_settings->asset_pack) == 0) current_pack = asset_packs_size(app->asset_packs); + } + } + } while(false); + free(name); + storage_file_free(folder); + furi_record_close(RECORD_STORAGE); + + item = variable_item_list_add( + var_item_list, + "Base Graphics", + 2, + xtreme_settings_scene_start_base_graphics_changed, + app); + variable_item_set_current_value_index(item, xtreme_settings->nsfw_mode); + variable_item_set_current_value_text(item, xtreme_settings->nsfw_mode ? "NSFW" : "SFW"); + + item = variable_item_list_add( + var_item_list, + "Asset Pack", + asset_packs_size(app->asset_packs) + 1, + xtreme_settings_scene_start_asset_pack_changed, + app); + variable_item_set_current_value_index(item, current_pack); + variable_item_set_current_value_text(item, current_pack == 0 ? "OFF" : *asset_packs_get(app->asset_packs, current_pack - 1)); + + item = variable_item_list_add( + var_item_list, + "Anim Speed", + COUNT_OF(anim_speed_names), + xtreme_settings_scene_start_anim_speed_changed, + app); + value_index = value_index_int32( + xtreme_settings->anim_speed, anim_speed_values, COUNT_OF(anim_speed_names)); + variable_item_set_current_value_index(item, value_index); + variable_item_set_current_value_text(item, anim_speed_names[value_index]); + + item = variable_item_list_add( + var_item_list, + "Cycle Anims", + COUNT_OF(cycle_anims_names), + xtreme_settings_scene_start_cycle_anims_changed, + app); + value_index = value_index_int32( + xtreme_settings->cycle_anims, cycle_anims_values, COUNT_OF(cycle_anims_names)); + variable_item_set_current_value_index(item, value_index); + variable_item_set_current_value_text(item, cycle_anims_names[value_index]); + + item = variable_item_list_add( + var_item_list, + "Unlock Anims", + 2, + xtreme_settings_scene_start_unlock_anims_changed, + app); + variable_item_set_current_value_index(item, xtreme_settings->unlock_anims); + variable_item_set_current_value_text(item, xtreme_settings->unlock_anims ? "ON" : "OFF"); + + item = variable_item_list_add( + var_item_list, + "Battery Style", + COUNT_OF(battery_style_names), + xtreme_settings_scene_start_battery_style_changed, + app); + value_index = value_index_int32( + xtreme_settings->battery_style, battery_style_values, COUNT_OF(battery_style_names)); + variable_item_set_current_value_index(item, value_index); + variable_item_set_current_value_text(item, battery_style_names[value_index]); + + char level_str[4]; + snprintf(level_str, 4, "%i", app->dolphin_level); + item = variable_item_list_add( + var_item_list, + "XP Level", + DOLPHIN_LEVEL_COUNT + 1, + xtreme_settings_scene_start_xp_level_changed, + app); + variable_item_set_current_value_index(item, app->dolphin_level - 1); + variable_item_set_current_value_text(item, level_str); + + item = variable_item_list_add( + var_item_list, + "SubGHz Extend", + 2, + xtreme_settings_scene_start_subghz_extend_changed, + app); + variable_item_set_current_value_index(item, app->subghz_extend); + variable_item_set_current_value_text(item, app->subghz_extend ? "ON" : "OFF"); + + item = variable_item_list_add( + var_item_list, + "SubGHz Bypass", + 2, + xtreme_settings_scene_start_subghz_bypass_changed, + app); + variable_item_set_current_value_index(item, app->subghz_bypass); + variable_item_set_current_value_text(item, app->subghz_bypass ? "ON" : "OFF"); + + FuriString* version_tag = furi_string_alloc_printf("%s %s", version_get_gitbranchnum(NULL), version_get_builddate(NULL)); + item = variable_item_list_add( + var_item_list, + furi_string_get_cstr(version_tag), + 0, + NULL, + app); + + view_dispatcher_switch_to_view(app->view_dispatcher, XtremeSettingsAppViewVarItemList); +} + +bool xtreme_settings_scene_start_on_event(void* context, SceneManagerEvent event) { + UNUSED(context); + UNUSED(event); + bool consumed = false; + return consumed; +} + +void xtreme_settings_scene_start_on_exit(void* context) { + XtremeSettingsApp* app = context; + asset_packs_it_t it; + for (asset_packs_it(it, app->asset_packs); !asset_packs_end_p(it); asset_packs_next(it)) { + free(*asset_packs_cref(it)); + } + asset_packs_clear(app->asset_packs); + variable_item_list_reset(app->var_item_list); +} diff --git a/applications/settings/xtreme_settings/xtreme_assets.c b/applications/settings/xtreme_settings/xtreme_assets.c new file mode 100644 index 0000000000..444b50951f --- /dev/null +++ b/applications/settings/xtreme_settings/xtreme_assets.c @@ -0,0 +1,123 @@ +#include "xtreme_assets.h" +#include "assets_icons.h" +#include + +XtremeAssets* xtreme_assets = NULL; + +XtremeAssets* XTREME_ASSETS() { + if (xtreme_assets == NULL) { + XTREME_ASSETS_LOAD(); + } + return xtreme_assets; +} + +void XTREME_ASSETS_LOAD() { + if (xtreme_assets != NULL) return; + + xtreme_assets = malloc(sizeof(XtremeAssets)); + XtremeSettings* xtreme_settings = XTREME_SETTINGS(); + + if (xtreme_settings->nsfw_mode) { + xtreme_assets->I_BLE_Pairing_128x64 = &I_BLE_Pairing_128x64; + xtreme_assets->I_DolphinCommon_56x48 = &I_DolphinCommon_56x48; + xtreme_assets->I_DolphinMafia_115x62 = &I_DolphinMafia_115x62; + xtreme_assets->I_DolphinNice_96x59 = &I_DolphinNice_96x59; + xtreme_assets->I_DolphinWait_61x59 = &I_DolphinWait_61x59; + xtreme_assets->I_iButtonDolphinVerySuccess_108x52 = &I_iButtonDolphinVerySuccess_108x52; + xtreme_assets->I_DolphinReadingSuccess_59x63 = &I_DolphinReadingSuccess_59x63; + xtreme_assets->I_NFC_dolphin_emulation_47x61 = &I_NFC_dolphin_emulation_47x61; + xtreme_assets->I_passport_bad_46x49 = &I_flipper; + xtreme_assets->I_passport_DB = &I_passport_DB; + xtreme_assets->I_passport_happy_46x49 = &I_flipper; + xtreme_assets->I_passport_okay_46x49 = &I_flipper; + xtreme_assets->I_RFIDDolphinReceive_97x61 = &I_RFIDDolphinReceive_97x61; + xtreme_assets->I_RFIDDolphinSend_97x61 = &I_RFIDDolphinSend_97x61; + xtreme_assets->I_RFIDDolphinSuccess_108x57 = &I_RFIDDolphinSuccess_108x57; + xtreme_assets->I_Cry_dolph_55x52 = &I_Cry_dolph_55x52; + xtreme_assets->I_Scanning_123x52 = &I_Scanning_123x52; + xtreme_assets->I_Auth_62x31 = &I_Auth_62x31; + xtreme_assets->I_Connect_me_62x31 = &I_Connect_me_62x31; + xtreme_assets->I_Connected_62x31 = &I_Connected_62x31; + xtreme_assets->I_Error_62x31 = &I_Error_62x31; + } else { + xtreme_assets->I_BLE_Pairing_128x64 = &I_BLE_Pairing_128x64_sfw; + xtreme_assets->I_DolphinCommon_56x48 = &I_DolphinCommon_56x48_sfw; + xtreme_assets->I_DolphinMafia_115x62 = &I_DolphinMafia_115x62_sfw; + xtreme_assets->I_DolphinNice_96x59 = &I_DolphinNice_96x59_sfw; + xtreme_assets->I_DolphinWait_61x59 = &I_DolphinWait_61x59_sfw; + xtreme_assets->I_iButtonDolphinVerySuccess_108x52 = &I_iButtonDolphinVerySuccess_108x52_sfw; + xtreme_assets->I_DolphinReadingSuccess_59x63 = &I_DolphinReadingSuccess_59x63_sfw; + xtreme_assets->I_NFC_dolphin_emulation_47x61 = &I_NFC_dolphin_emulation_47x61_sfw; + xtreme_assets->I_passport_bad_46x49 = &I_passport_bad1_46x49_sfw; + xtreme_assets->I_passport_DB = &I_passport_DB_sfw; + xtreme_assets->I_passport_happy_46x49 = &I_passport_happy1_46x49_sfw; + xtreme_assets->I_passport_okay_46x49 = &I_passport_okay1_46x49_sfw; + xtreme_assets->I_RFIDDolphinReceive_97x61 = &I_RFIDDolphinReceive_97x61_sfw; + xtreme_assets->I_RFIDDolphinSend_97x61 = &I_RFIDDolphinSend_97x61_sfw; + xtreme_assets->I_RFIDDolphinSuccess_108x57 = &I_RFIDDolphinSuccess_108x57_sfw; + xtreme_assets->I_Cry_dolph_55x52 = &I_Cry_dolph_55x52_sfw; + xtreme_assets->I_Scanning_123x52 = &I_Scanning_123x52_sfw; + xtreme_assets->I_Auth_62x31 = &I_Auth_62x31_sfw; + xtreme_assets->I_Connect_me_62x31 = &I_Connect_me_62x31_sfw; + xtreme_assets->I_Connected_62x31 = &I_Connected_62x31_sfw; + xtreme_assets->I_Error_62x31 = &I_Error_62x31_sfw; + } + + if (xtreme_settings->asset_pack[0] == '\0') return; + FileInfo info; + FuriString* path = furi_string_alloc(); + const char* pack = xtreme_settings->asset_pack; + furi_string_printf(path, PACKS_DIR "/%s", pack); + Storage* storage = furi_record_open(RECORD_STORAGE); + if (storage_common_stat(storage, furi_string_get_cstr(path), &info) == FSE_OK && info.flags & FSF_DIRECTORY) { + File* file = storage_file_alloc(storage); + + swap_bmx_icon(&xtreme_assets->I_BLE_Pairing_128x64, pack, "BLE/BLE_Pairing_128x64.bmx", path, file); + swap_bmx_icon(&xtreme_assets->I_DolphinCommon_56x48, pack, "Dolphin/DolphinCommon_56x48.bmx", path, file); + swap_bmx_icon(&xtreme_assets->I_DolphinMafia_115x62, pack, "iButton/DolphinMafia_115x62.bmx", path, file); + swap_bmx_icon(&xtreme_assets->I_DolphinNice_96x59, pack, "iButton/DolphinNice_96x59.bmx", path, file); + swap_bmx_icon(&xtreme_assets->I_DolphinWait_61x59, pack, "iButton/DolphinWait_61x59.bmx", path, file); + swap_bmx_icon(&xtreme_assets->I_iButtonDolphinVerySuccess_108x52, pack, "iButton/iButtonDolphinVerySuccess_108x52.bmx", path, file); + swap_bmx_icon(&xtreme_assets->I_DolphinReadingSuccess_59x63, pack, "Infrared/DolphinReadingSuccess_59x63.bmx", path, file); + swap_bmx_icon(&xtreme_assets->I_NFC_dolphin_emulation_47x61, pack, "NFC/NFC_dolphin_emulation_47x61.bmx", path, file); + swap_bmx_icon(&xtreme_assets->I_passport_bad_46x49, pack, "Passport/passport_bad_46x49.bmx", path, file); + swap_bmx_icon(&xtreme_assets->I_passport_DB, pack, "Passport/passport_DB.bmx", path, file); + swap_bmx_icon(&xtreme_assets->I_passport_happy_46x49, pack, "Passport/passport_happy_46x49.bmx", path, file); + swap_bmx_icon(&xtreme_assets->I_passport_okay_46x49, pack, "Passport/passport_okay_46x49.bmx", path, file); + swap_bmx_icon(&xtreme_assets->I_RFIDDolphinReceive_97x61, pack, "RFID/RFIDDolphinReceive_97x61.bmx", path, file); + swap_bmx_icon(&xtreme_assets->I_RFIDDolphinSend_97x61, pack, "RFID/RFIDDolphinSend_97x61.bmx", path, file); + swap_bmx_icon(&xtreme_assets->I_RFIDDolphinSuccess_108x57, pack, "RFID/RFIDDolphinSuccess_108x57.bmx", path, file); + swap_bmx_icon(&xtreme_assets->I_Cry_dolph_55x52, pack, "Settings/Cry_dolph_55x52.bmx", path, file); + swap_bmx_icon(&xtreme_assets->I_Scanning_123x52, pack, "SubGhz/Scanning_123x52.bmx", path, file); + swap_bmx_icon(&xtreme_assets->I_Auth_62x31, pack, "U2F/Auth_62x31.bmx", path, file); + swap_bmx_icon(&xtreme_assets->I_Connect_me_62x31, pack, "U2F/Connect_me_62x31.bmx", path, file); + swap_bmx_icon(&xtreme_assets->I_Connected_62x31, pack, "U2F/Connected_62x31.bmx", path, file); + swap_bmx_icon(&xtreme_assets->I_Error_62x31, pack, "U2F/Error_62x31.bmx", path, file); + + storage_file_free(file); + } + furi_record_close(RECORD_STORAGE); + furi_string_free(path); +} + +void swap_bmx_icon(const Icon** replace, const char* pack, const char* name, FuriString* path, File* file) { + furi_string_printf(path, PACKS_DIR "/%s/Icons/%s", pack, name); + if (storage_file_open(file, furi_string_get_cstr(path), FSAM_READ, FSOM_OPEN_EXISTING)) { + uint64_t size = storage_file_size(file) - 8; + int32_t width, height; + storage_file_read(file, &width, 4); + storage_file_read(file, &height, 4); + + Icon* icon = malloc(sizeof(Icon)); + FURI_CONST_ASSIGN(icon->frame_count, 1); + FURI_CONST_ASSIGN(icon->frame_rate, 0); + FURI_CONST_ASSIGN(icon->width, width); + FURI_CONST_ASSIGN(icon->height, height); + icon->frames = malloc(sizeof(const uint8_t*)); + FURI_CONST_ASSIGN_PTR(icon->frames[0], malloc(size)); + storage_file_read(file, (void*)icon->frames[0], size); + *replace = icon; + + storage_file_close(file); + } +} diff --git a/applications/settings/xtreme_settings/xtreme_assets.h b/applications/settings/xtreme_settings/xtreme_assets.h new file mode 100644 index 0000000000..df618c47db --- /dev/null +++ b/applications/settings/xtreme_settings/xtreme_assets.h @@ -0,0 +1,39 @@ +#pragma once + +#include +#include "xtreme_settings.h" +#include + +#define PACKS_DIR EXT_PATH("dolphin_custom") + +typedef struct { + const Icon* I_BLE_Pairing_128x64; + const Icon* I_DolphinCommon_56x48; + const Icon* I_DolphinMafia_115x62; + const Icon* I_DolphinNice_96x59; + const Icon* I_DolphinWait_61x59; + const Icon* I_iButtonDolphinVerySuccess_108x52; + const Icon* I_DolphinReadingSuccess_59x63; + const Icon* I_NFC_dolphin_emulation_47x61; + const Icon* I_passport_bad_46x49; + const Icon* I_passport_DB; + const Icon* I_passport_happy_46x49; + const Icon* I_passport_okay_46x49; + const Icon* I_RFIDDolphinReceive_97x61; + const Icon* I_RFIDDolphinSend_97x61; + const Icon* I_RFIDDolphinSuccess_108x57; + const Icon* I_Cry_dolph_55x52; + const Icon* I_Scanning_123x52; + const Icon* I_Auth_62x31; + const Icon* I_Connect_me_62x31; + const Icon* I_Connected_62x31; + const Icon* I_Error_62x31; +} XtremeAssets; + +XtremeAssets* XTREME_ASSETS(); + +void XTREME_ASSETS_LOAD(); + +void swap_bmx_icon(const Icon** replace, const char* base, const char* name, FuriString* path, File* file); + +void free_bmx_icon(Icon* icon); diff --git a/applications/settings/xtreme_settings/xtreme_settings.c b/applications/settings/xtreme_settings/xtreme_settings.c new file mode 100644 index 0000000000..84018bcf00 --- /dev/null +++ b/applications/settings/xtreme_settings/xtreme_settings.c @@ -0,0 +1,32 @@ +#include "xtreme_settings.h" + +XtremeSettings* xtreme_settings = NULL; + +XtremeSettings* XTREME_SETTINGS() { + if (xtreme_settings == NULL) { + XTREME_SETTINGS_LOAD(); + } + return xtreme_settings; +} + +bool XTREME_SETTINGS_LOAD() { + if (xtreme_settings == NULL) { + xtreme_settings = malloc(sizeof(XtremeSettings)); + bool loaded = saved_struct_load( + XTREME_SETTINGS_PATH, xtreme_settings, sizeof(XtremeSettings), XTREME_SETTINGS_MAGIC, XTREME_SETTINGS_VERSION); + if(!loaded) { + memset(xtreme_settings, 0, sizeof(XtremeSettings)); + loaded = XTREME_SETTINGS_SAVE(); + } + return loaded; + } + return true; +} + +bool XTREME_SETTINGS_SAVE() { + if (xtreme_settings == NULL) { + XTREME_SETTINGS_LOAD(); + } + return saved_struct_save( + XTREME_SETTINGS_PATH, xtreme_settings, sizeof(XtremeSettings), XTREME_SETTINGS_MAGIC, XTREME_SETTINGS_VERSION); +} diff --git a/applications/settings/xtreme_settings/xtreme_settings.h b/applications/settings/xtreme_settings/xtreme_settings.h new file mode 100644 index 0000000000..0a19ca6433 --- /dev/null +++ b/applications/settings/xtreme_settings/xtreme_settings.h @@ -0,0 +1,31 @@ +#pragma once + +#include "xtreme_settings_filename.h" + +#include +#include +#include +#include +#include +#include + +#define MAX_PACK_NAME_LEN 32 + +#define XTREME_SETTINGS_VERSION (1) +#define XTREME_SETTINGS_PATH INT_PATH(XTREME_SETTINGS_FILE_NAME) +#define XTREME_SETTINGS_MAGIC (0x69) + +typedef struct { + int32_t cycle_anims; + bool unlock_anims; + bool nsfw_mode; + char asset_pack[MAX_PACK_NAME_LEN]; + BatteryStyle battery_style; + uint16_t anim_speed; +} XtremeSettings; + +XtremeSettings* XTREME_SETTINGS(); + +bool XTREME_SETTINGS_LOAD(); + +bool XTREME_SETTINGS_SAVE(); diff --git a/applications/settings/xtreme_settings/xtreme_settings_app.c b/applications/settings/xtreme_settings/xtreme_settings_app.c new file mode 100644 index 0000000000..780e767302 --- /dev/null +++ b/applications/settings/xtreme_settings/xtreme_settings_app.c @@ -0,0 +1,117 @@ +#include "xtreme_settings_app.h" + +static bool xtreme_settings_custom_event_callback(void* context, uint32_t event) { + furi_assert(context); + XtremeSettingsApp* app = context; + return scene_manager_handle_custom_event(app->scene_manager, event); +} + +void xtreme_settings_reboot(void* context) { + UNUSED(context); + power_reboot(PowerBootModeNormal); +} + +static bool xtreme_settings_back_event_callback(void* context) { + furi_assert(context); + XtremeSettingsApp* app = context; + + if (app->level_changed) { + Dolphin* dolphin = furi_record_open(RECORD_DOLPHIN); + DolphinStats stats = dolphin_stats(dolphin); + if (app->dolphin_level != stats.level) { + int xp = app->dolphin_level > 1 ? dolphin_get_levels()[app->dolphin_level - 2] : 0; + dolphin->state->data.icounter = xp + 1; + dolphin->state->dirty = true; + dolphin_state_save(dolphin->state); + } + furi_record_close(RECORD_DOLPHIN); + } + + if (app->subghz_changed) { + Storage* storage = furi_record_open(RECORD_STORAGE); + FlipperFormat* subghz_range = flipper_format_file_alloc(storage); + if(flipper_format_file_open_existing(subghz_range, "/ext/subghz/assets/extend_range.txt")) { + flipper_format_insert_or_update_bool(subghz_range, "use_ext_range_at_own_risk", &app->subghz_extend, 1); + flipper_format_insert_or_update_bool(subghz_range, "ignore_default_tx_region", &app->subghz_bypass, 1); + } + flipper_format_free(subghz_range); + furi_record_close(RECORD_STORAGE); + } + + if (app->settings_changed) { + XTREME_SETTINGS_SAVE(); + if (app->assets_changed) { + popup_set_header(app->popup, "Rebooting...", 64, 26, AlignCenter, AlignCenter); + popup_set_text(app->popup, "Swapping assets...", 64, 40, AlignCenter, AlignCenter); + popup_set_callback(app->popup, xtreme_settings_reboot); + popup_set_context(app->popup, app); + popup_set_timeout(app->popup, 1000); + popup_enable_timeout(app->popup); + view_dispatcher_switch_to_view(app->view_dispatcher, XtremeSettingsAppViewPopup); + return true; + } + } + + return scene_manager_handle_back_event(app->scene_manager); +} + +XtremeSettingsApp* xtreme_settings_app_alloc() { + XtremeSettingsApp* app = malloc(sizeof(XtremeSettingsApp)); + app->gui = furi_record_open(RECORD_GUI); + + // View Dispatcher and Scene Manager + app->view_dispatcher = view_dispatcher_alloc(); + app->scene_manager = scene_manager_alloc(&xtreme_settings_scene_handlers, app); + view_dispatcher_enable_queue(app->view_dispatcher); + view_dispatcher_set_event_callback_context(app->view_dispatcher, app); + + view_dispatcher_set_custom_event_callback( + app->view_dispatcher, xtreme_settings_custom_event_callback); + view_dispatcher_set_navigation_event_callback( + app->view_dispatcher, xtreme_settings_back_event_callback); + + view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen); + + // Gui Modules + app->var_item_list = variable_item_list_alloc(); + view_dispatcher_add_view( + app->view_dispatcher, + XtremeSettingsAppViewVarItemList, + variable_item_list_get_view(app->var_item_list)); + + app->popup = popup_alloc(); + view_dispatcher_add_view( + app->view_dispatcher, + XtremeSettingsAppViewPopup, + popup_get_view(app->popup)); + + // Set first scene + scene_manager_next_scene(app->scene_manager, XtremeSettingsAppSceneStart); + return app; +} + +void xtreme_settings_app_free(XtremeSettingsApp* app) { + furi_assert(app); + + // Gui modules + view_dispatcher_remove_view(app->view_dispatcher, XtremeSettingsAppViewVarItemList); + variable_item_list_free(app->var_item_list); + view_dispatcher_remove_view(app->view_dispatcher, XtremeSettingsAppViewPopup); + popup_free(app->popup); + + // View Dispatcher and Scene Manager + view_dispatcher_free(app->view_dispatcher); + scene_manager_free(app->scene_manager); + + // Records + furi_record_close(RECORD_GUI); + free(app); +} + +extern int32_t xtreme_settings_app(void* p) { + UNUSED(p); + XtremeSettingsApp* app = xtreme_settings_app_alloc(); + view_dispatcher_run(app->view_dispatcher); + xtreme_settings_app_free(app); + return 0; +} diff --git a/applications/settings/xtreme_settings/xtreme_settings_app.h b/applications/settings/xtreme_settings/xtreme_settings_app.h new file mode 100644 index 0000000000..7265da078e --- /dev/null +++ b/applications/settings/xtreme_settings/xtreme_settings_app.h @@ -0,0 +1,41 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include "xtreme_settings.h" +#include "xtreme_assets.h" +#include "scenes/xtreme_settings_scene.h" +#include "dolphin/helpers/dolphin_state.h" +#include "dolphin/dolphin.h" +#include "dolphin/dolphin_i.h" +#include +#include + +ARRAY_DEF(asset_packs, char*) + +typedef struct { + Gui* gui; + SceneManager* scene_manager; + ViewDispatcher* view_dispatcher; + VariableItemList* var_item_list; + Popup* popup; + int dolphin_level; + bool subghz_extend; + bool subghz_bypass; + bool settings_changed; + bool assets_changed; + bool subghz_changed; + bool level_changed; + asset_packs_t asset_packs; +} XtremeSettingsApp; + +typedef enum { + XtremeSettingsAppViewVarItemList, + XtremeSettingsAppViewPopup, +} XtremeSettingsAppView; diff --git a/applications/settings/xtreme_settings/xtreme_settings_filename.h b/applications/settings/xtreme_settings/xtreme_settings_filename.h new file mode 100644 index 0000000000..c2706c76ea --- /dev/null +++ b/applications/settings/xtreme_settings/xtreme_settings_filename.h @@ -0,0 +1,3 @@ +#pragma once + +#define XTREME_SETTINGS_FILE_NAME ".xtreme.settings" diff --git a/assets/SConscript b/assets/SConscript index b078e0f419..aace521d28 100644 --- a/assets/SConscript +++ b/assets/SConscript @@ -54,13 +54,14 @@ assetsenv.Alias("proto_ver", proto_ver) # Gather everything into a static lib assets_parts = (icons, proto, dolphin_blocking, dolphin_internal, proto_ver) +env.Replace(FW_ASSETS_HEADERS=assets_parts) assetslib = assetsenv.Library("${FW_LIB_NAME}", assets_parts) assetsenv.Install("${LIB_DIST_DIR}", assetslib) # Resources for SD card - +env.SetDefault(FW_RESOURCES=None) if assetsenv["IS_BASE_FIRMWARE"]: # External dolphin animations dolphin_external = assetsenv.DolphinExtBuilder( @@ -92,8 +93,7 @@ if assetsenv["IS_BASE_FIRMWARE"]: ) # Exporting resources node to external environment - env["FW_ASSETS_HEADERS"] = assets_parts - env["FW_RESOURCES"] = resources + env.Replace(FW_RESOURCES=resources) assetsenv.Alias("resources", resources) Return("assetslib") \ No newline at end of file diff --git a/assets/dolphin/ReadMe.md b/assets/dolphin/ReadMe.md index e7572571ca..5f4932c530 100644 --- a/assets/dolphin/ReadMe.md +++ b/assets/dolphin/ReadMe.md @@ -2,9 +2,12 @@ Dolphin assets are split into 3 parts: -- blocking - Essential animations that are used for blocking system notifications. They are packed to `assets_dolphin_blocking.[h,c]`. -- internal - Internal animations that are used for idle dolphin animation. Converted to `assets_dolphin_internal.[h,c]`. -- external - External animations that are used for idle dolphin animation. Packed to resource folder and placed on SD card. +- blocking - Essential animations that are used for blocking system notifications. They are packed to `assets_dolphin_blocking.[h,c]`. +- internal - Last fallback animations that are used for idle dolphin animation. Converted to `assets_dolphin_internal.[h,c]`. +- external - Essential animations that are used for idle dolphin animation. Compiled to `.bm` and found at `SD/dolphin/`. + +- custom - Custom User-made animations that are used for a variety of scenes, such as `dolphin idle, passport, scanning`. Compiled to `.bmx` and found at `SD/dolphin_custom` + # Files diff --git a/assets/dolphin/custom/WatchDogs/Anims/BOTTY_CALL/frame_0.png b/assets/dolphin/custom/WatchDogs/Anims/BOTTY_CALL/frame_0.png new file mode 100644 index 0000000000..89f2c196d2 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/BOTTY_CALL/frame_0.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/BOTTY_CALL/frame_1.png b/assets/dolphin/custom/WatchDogs/Anims/BOTTY_CALL/frame_1.png new file mode 100644 index 0000000000..a102a5a2f4 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/BOTTY_CALL/frame_1.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/BOTTY_CALL/frame_2.png b/assets/dolphin/custom/WatchDogs/Anims/BOTTY_CALL/frame_2.png new file mode 100644 index 0000000000..c87f751269 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/BOTTY_CALL/frame_2.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/BOTTY_CALL/meta.txt b/assets/dolphin/custom/WatchDogs/Anims/BOTTY_CALL/meta.txt new file mode 100644 index 0000000000..0a08fc2a7e --- /dev/null +++ b/assets/dolphin/custom/WatchDogs/Anims/BOTTY_CALL/meta.txt @@ -0,0 +1,14 @@ +Filetype: Flipper Animation +Version: 1 + +Width: 128 +Height: 64 +Passive frames: 3 +Active frames: 0 +Frames order: 0 1 2 +Active cycles: 0 +Frame rate: 2 +Duration: 3600 +Active cooldown: 0 + +Bubble slots: 0 diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_AD/frame_0.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_AD/frame_0.png new file mode 100644 index 0000000000..84a8860e8c Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_AD/frame_0.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_AD/frame_1.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_AD/frame_1.png new file mode 100644 index 0000000000..e1a05efe78 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_AD/frame_1.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_AD/frame_10.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_AD/frame_10.png new file mode 100644 index 0000000000..8ca3fc196a Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_AD/frame_10.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_AD/frame_11.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_AD/frame_11.png new file mode 100644 index 0000000000..cc33eae2b9 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_AD/frame_11.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_AD/frame_12.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_AD/frame_12.png new file mode 100644 index 0000000000..b9e222ea6a Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_AD/frame_12.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_AD/frame_13.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_AD/frame_13.png new file mode 100644 index 0000000000..ba7e5d2f6f Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_AD/frame_13.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_AD/frame_14.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_AD/frame_14.png new file mode 100644 index 0000000000..b8c411f6d3 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_AD/frame_14.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_AD/frame_15.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_AD/frame_15.png new file mode 100644 index 0000000000..bd01a0089a Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_AD/frame_15.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_AD/frame_16.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_AD/frame_16.png new file mode 100644 index 0000000000..d2d9691fc9 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_AD/frame_16.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_AD/frame_2.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_AD/frame_2.png new file mode 100644 index 0000000000..34ec147a94 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_AD/frame_2.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_AD/frame_3.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_AD/frame_3.png new file mode 100644 index 0000000000..6372688365 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_AD/frame_3.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_AD/frame_4.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_AD/frame_4.png new file mode 100644 index 0000000000..47d222eab7 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_AD/frame_4.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_AD/frame_5.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_AD/frame_5.png new file mode 100644 index 0000000000..413cdfe398 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_AD/frame_5.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_AD/frame_6.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_AD/frame_6.png new file mode 100644 index 0000000000..ef177bda4e Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_AD/frame_6.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_AD/frame_7.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_AD/frame_7.png new file mode 100644 index 0000000000..b05c1d62c8 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_AD/frame_7.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_AD/frame_8.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_AD/frame_8.png new file mode 100644 index 0000000000..413cdfe398 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_AD/frame_8.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_AD/frame_9.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_AD/frame_9.png new file mode 100644 index 0000000000..800a9b63d3 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_AD/frame_9.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_AD/meta.txt b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_AD/meta.txt new file mode 100644 index 0000000000..4991b01ee8 --- /dev/null +++ b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_AD/meta.txt @@ -0,0 +1,14 @@ +Filetype: Flipper Animation +Version: 1 + +Width: 128 +Height: 64 +Passive frames: 17 +Active frames: 0 +Frames order: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 +Active cycles: 0 +Frame rate: 4 +Duration: 3600 +Active cooldown: 0 + +Bubble slots: 0 diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_0.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_0.png new file mode 100644 index 0000000000..72f4a62565 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_0.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_1.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_1.png new file mode 100644 index 0000000000..85b9ca70a7 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_1.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_10.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_10.png new file mode 100644 index 0000000000..4315734b1a Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_10.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_11.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_11.png new file mode 100644 index 0000000000..7b0643fda9 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_11.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_12.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_12.png new file mode 100644 index 0000000000..00d15664e3 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_12.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_13.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_13.png new file mode 100644 index 0000000000..a7b0b0350b Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_13.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_14.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_14.png new file mode 100644 index 0000000000..1d602b70b5 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_14.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_15.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_15.png new file mode 100644 index 0000000000..84719755a0 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_15.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_16.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_16.png new file mode 100644 index 0000000000..88fa03a817 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_16.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_17.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_17.png new file mode 100644 index 0000000000..2a2a41929c Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_17.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_18.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_18.png new file mode 100644 index 0000000000..9be47be36e Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_18.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_19.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_19.png new file mode 100644 index 0000000000..bac895c6a0 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_19.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_2.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_2.png new file mode 100644 index 0000000000..fd1764eed1 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_2.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_20.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_20.png new file mode 100644 index 0000000000..6b50803485 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_20.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_21.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_21.png new file mode 100644 index 0000000000..e5ae801850 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_21.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_22.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_22.png new file mode 100644 index 0000000000..7b399ee504 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_22.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_23.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_23.png new file mode 100644 index 0000000000..db4dcc368d Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_23.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_24.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_24.png new file mode 100644 index 0000000000..bd14e10d45 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_24.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_25.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_25.png new file mode 100644 index 0000000000..fff0885ba0 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_25.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_26.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_26.png new file mode 100644 index 0000000000..d51d807fa0 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_26.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_27.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_27.png new file mode 100644 index 0000000000..7f87ea1822 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_27.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_28.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_28.png new file mode 100644 index 0000000000..f1d9447f42 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_28.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_29.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_29.png new file mode 100644 index 0000000000..1d173bcebb Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_29.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_3.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_3.png new file mode 100644 index 0000000000..f06d7da7f8 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_3.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_30.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_30.png new file mode 100644 index 0000000000..3c5f59a7c6 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_30.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_31.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_31.png new file mode 100644 index 0000000000..a6bb50bcb4 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_31.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_32.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_32.png new file mode 100644 index 0000000000..8376e8adaf Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_32.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_33.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_33.png new file mode 100644 index 0000000000..46564c9447 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_33.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_34.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_34.png new file mode 100644 index 0000000000..ddc72be209 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_34.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_35.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_35.png new file mode 100644 index 0000000000..192828c634 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_35.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_36.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_36.png new file mode 100644 index 0000000000..5a39cc8f43 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_36.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_37.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_37.png new file mode 100644 index 0000000000..1df0d3fd59 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_37.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_38.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_38.png new file mode 100644 index 0000000000..612d13e641 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_38.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_39.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_39.png new file mode 100644 index 0000000000..9bd001f81e Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_39.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_4.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_4.png new file mode 100644 index 0000000000..ae563faf2f Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_4.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_40.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_40.png new file mode 100644 index 0000000000..589566842e Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_40.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_41.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_41.png new file mode 100644 index 0000000000..1521a40744 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_41.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_5.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_5.png new file mode 100644 index 0000000000..f05234aad9 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_5.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_6.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_6.png new file mode 100644 index 0000000000..13850f72f5 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_6.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_7.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_7.png new file mode 100644 index 0000000000..f0c8c4d3ac Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_7.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_8.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_8.png new file mode 100644 index 0000000000..10bcce799c Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_8.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_9.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_9.png new file mode 100644 index 0000000000..4bd2791ec7 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/frame_9.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/meta.txt b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/meta.txt new file mode 100644 index 0000000000..1f2937d970 --- /dev/null +++ b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ANIM/meta.txt @@ -0,0 +1,14 @@ +Filetype: Flipper Animation +Version: 1 + +Width: 128 +Height: 64 +Passive frames: 42 +Active frames: 0 +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 +Active cycles: 0 +Frame rate: 6 +Duration: 3600 +Active cooldown: 0 + +Bubble slots: 0 diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ASCII/frame_0.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ASCII/frame_0.png new file mode 100644 index 0000000000..f06b781dd8 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ASCII/frame_0.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ASCII/frame_1.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ASCII/frame_1.png new file mode 100644 index 0000000000..a968025182 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ASCII/frame_1.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ASCII/frame_10.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ASCII/frame_10.png new file mode 100644 index 0000000000..11cdc6413c Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ASCII/frame_10.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ASCII/frame_2.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ASCII/frame_2.png new file mode 100644 index 0000000000..0dbd6e3911 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ASCII/frame_2.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ASCII/frame_3.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ASCII/frame_3.png new file mode 100644 index 0000000000..318e7d8d1c Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ASCII/frame_3.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ASCII/frame_4.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ASCII/frame_4.png new file mode 100644 index 0000000000..7474d507bc Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ASCII/frame_4.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ASCII/frame_5.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ASCII/frame_5.png new file mode 100644 index 0000000000..9e321f4637 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ASCII/frame_5.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ASCII/frame_6.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ASCII/frame_6.png new file mode 100644 index 0000000000..7fda8b2934 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ASCII/frame_6.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ASCII/frame_7.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ASCII/frame_7.png new file mode 100644 index 0000000000..29019b8560 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ASCII/frame_7.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ASCII/frame_8.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ASCII/frame_8.png new file mode 100644 index 0000000000..800337227e Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ASCII/frame_8.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ASCII/frame_9.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ASCII/frame_9.png new file mode 100644 index 0000000000..53ec9c9e1f Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ASCII/frame_9.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ASCII/meta.txt b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ASCII/meta.txt new file mode 100644 index 0000000000..c601480501 --- /dev/null +++ b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_ASCII/meta.txt @@ -0,0 +1,14 @@ +Filetype: Flipper Animation +Version: 1 + +Width: 128 +Height: 64 +Passive frames: 11 +Active frames: 0 +Frames order: 0 1 2 3 4 5 6 7 8 9 10 +Active cycles: 0 +Frame rate: 4 +Duration: 3600 +Active cooldown: 0 + +Bubble slots: 0 diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_0.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_0.png new file mode 100644 index 0000000000..7c68b5c648 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_0.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_1.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_1.png new file mode 100644 index 0000000000..9a69729cd2 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_1.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_10.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_10.png new file mode 100644 index 0000000000..59499872f3 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_10.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_11.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_11.png new file mode 100644 index 0000000000..608cd51d3d Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_11.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_12.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_12.png new file mode 100644 index 0000000000..2644b3f299 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_12.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_13.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_13.png new file mode 100644 index 0000000000..c1fafc5f3a Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_13.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_14.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_14.png new file mode 100644 index 0000000000..20ab846898 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_14.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_15.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_15.png new file mode 100644 index 0000000000..39f1586dfc Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_15.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_16.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_16.png new file mode 100644 index 0000000000..600d3fc9d9 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_16.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_17.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_17.png new file mode 100644 index 0000000000..c1ea260e94 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_17.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_18.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_18.png new file mode 100644 index 0000000000..5aa285babf Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_18.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_19.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_19.png new file mode 100644 index 0000000000..578c8c68cc Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_19.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_2.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_2.png new file mode 100644 index 0000000000..b8a3028536 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_2.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_20.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_20.png new file mode 100644 index 0000000000..5ed8d680ce Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_20.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_21.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_21.png new file mode 100644 index 0000000000..4ee1966401 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_21.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_22.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_22.png new file mode 100644 index 0000000000..aa60355e4f Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_22.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_23.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_23.png new file mode 100644 index 0000000000..2f8a2e1dd3 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_23.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_24.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_24.png new file mode 100644 index 0000000000..b8c38c7f48 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_24.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_25.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_25.png new file mode 100644 index 0000000000..3b77bc9f82 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_25.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_26.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_26.png new file mode 100644 index 0000000000..895ba22c92 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_26.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_27.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_27.png new file mode 100644 index 0000000000..b648d368f9 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_27.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_28.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_28.png new file mode 100644 index 0000000000..f2ae146c5c Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_28.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_29.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_29.png new file mode 100644 index 0000000000..88b2e9874e Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_29.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_3.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_3.png new file mode 100644 index 0000000000..e2ba0172a6 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_3.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_30.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_30.png new file mode 100644 index 0000000000..9c651c7fa2 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_30.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_31.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_31.png new file mode 100644 index 0000000000..bc860d94ef Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_31.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_4.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_4.png new file mode 100644 index 0000000000..2c2e4c1af6 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_4.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_5.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_5.png new file mode 100644 index 0000000000..3f2523b7ee Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_5.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_6.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_6.png new file mode 100644 index 0000000000..5fcecb87d7 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_6.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_7.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_7.png new file mode 100644 index 0000000000..2ba761d98a Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_7.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_8.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_8.png new file mode 100644 index 0000000000..9eeaaee605 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_8.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_9.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_9.png new file mode 100644 index 0000000000..780c8e9219 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/frame_9.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/meta.txt b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/meta.txt new file mode 100644 index 0000000000..64a5c94655 --- /dev/null +++ b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_LOGO/meta.txt @@ -0,0 +1,14 @@ +Filetype: Flipper Animation +Version: 1 + +Width: 128 +Height: 64 +Passive frames: 32 +Active frames: 0 +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 +Active cycles: 0 +Frame rate: 5 +Duration: 3600 +Active cooldown: 0 + +Bubble slots: 0 diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_OLD/frame_0.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_OLD/frame_0.png new file mode 100644 index 0000000000..6e9e44054d Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_OLD/frame_0.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_OLD/frame_1.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_OLD/frame_1.png new file mode 100644 index 0000000000..5acb5e5f3b Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_OLD/frame_1.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_OLD/frame_10.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_OLD/frame_10.png new file mode 100644 index 0000000000..4526961c17 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_OLD/frame_10.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_OLD/frame_11.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_OLD/frame_11.png new file mode 100644 index 0000000000..722800d87d Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_OLD/frame_11.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_OLD/frame_12.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_OLD/frame_12.png new file mode 100644 index 0000000000..6a48942f71 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_OLD/frame_12.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_OLD/frame_13.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_OLD/frame_13.png new file mode 100644 index 0000000000..2f0187928c Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_OLD/frame_13.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_OLD/frame_14.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_OLD/frame_14.png new file mode 100644 index 0000000000..589db0c77b Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_OLD/frame_14.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_OLD/frame_15.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_OLD/frame_15.png new file mode 100644 index 0000000000..4eda01bf3d Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_OLD/frame_15.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_OLD/frame_16.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_OLD/frame_16.png new file mode 100644 index 0000000000..a3e22804a4 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_OLD/frame_16.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_OLD/frame_17.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_OLD/frame_17.png new file mode 100644 index 0000000000..5fbf934f76 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_OLD/frame_17.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_OLD/frame_18.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_OLD/frame_18.png new file mode 100644 index 0000000000..4eda01bf3d Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_OLD/frame_18.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_OLD/frame_19.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_OLD/frame_19.png new file mode 100644 index 0000000000..589db0c77b Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_OLD/frame_19.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_OLD/frame_2.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_OLD/frame_2.png new file mode 100644 index 0000000000..3ca753499f Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_OLD/frame_2.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_OLD/frame_20.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_OLD/frame_20.png new file mode 100644 index 0000000000..4eda01bf3d Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_OLD/frame_20.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_OLD/frame_3.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_OLD/frame_3.png new file mode 100644 index 0000000000..ecf8bc022c Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_OLD/frame_3.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_OLD/frame_4.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_OLD/frame_4.png new file mode 100644 index 0000000000..ecf8bc022c Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_OLD/frame_4.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_OLD/frame_5.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_OLD/frame_5.png new file mode 100644 index 0000000000..0d24d77762 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_OLD/frame_5.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_OLD/frame_6.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_OLD/frame_6.png new file mode 100644 index 0000000000..c7a9236d21 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_OLD/frame_6.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_OLD/frame_7.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_OLD/frame_7.png new file mode 100644 index 0000000000..aa17d6355f Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_OLD/frame_7.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_OLD/frame_8.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_OLD/frame_8.png new file mode 100644 index 0000000000..824ee828ea Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_OLD/frame_8.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_OLD/frame_9.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_OLD/frame_9.png new file mode 100644 index 0000000000..1090e63905 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_OLD/frame_9.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_OLD/meta.txt b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_OLD/meta.txt new file mode 100644 index 0000000000..6dabe353ff --- /dev/null +++ b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_OLD/meta.txt @@ -0,0 +1,14 @@ +Filetype: Flipper Animation +Version: 1 + +Width: 128 +Height: 64 +Passive frames: 21 +Active frames: 0 +Frames order: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 +Active cycles: 0 +Frame rate: 4 +Duration: 3600 +Active cooldown: 0 + +Bubble slots: 0 diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_TALK/frame_0.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_TALK/frame_0.png new file mode 100644 index 0000000000..a3439432d2 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_TALK/frame_0.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_TALK/frame_1.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_TALK/frame_1.png new file mode 100644 index 0000000000..599aec4422 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_TALK/frame_1.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_TALK/frame_10.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_TALK/frame_10.png new file mode 100644 index 0000000000..e4392fb804 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_TALK/frame_10.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_TALK/frame_11.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_TALK/frame_11.png new file mode 100644 index 0000000000..2c20d624f5 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_TALK/frame_11.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_TALK/frame_12.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_TALK/frame_12.png new file mode 100644 index 0000000000..f8d7186784 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_TALK/frame_12.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_TALK/frame_13.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_TALK/frame_13.png new file mode 100644 index 0000000000..463ef005cd Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_TALK/frame_13.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_TALK/frame_14.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_TALK/frame_14.png new file mode 100644 index 0000000000..62cfc00c1a Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_TALK/frame_14.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_TALK/frame_15.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_TALK/frame_15.png new file mode 100644 index 0000000000..eb4f0818d7 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_TALK/frame_15.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_TALK/frame_16.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_TALK/frame_16.png new file mode 100644 index 0000000000..bdc8296987 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_TALK/frame_16.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_TALK/frame_17.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_TALK/frame_17.png new file mode 100644 index 0000000000..b8b84914b2 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_TALK/frame_17.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_TALK/frame_2.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_TALK/frame_2.png new file mode 100644 index 0000000000..3f875a2f3a Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_TALK/frame_2.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_TALK/frame_3.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_TALK/frame_3.png new file mode 100644 index 0000000000..0c7f45869f Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_TALK/frame_3.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_TALK/frame_4.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_TALK/frame_4.png new file mode 100644 index 0000000000..cc390c0f34 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_TALK/frame_4.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_TALK/frame_5.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_TALK/frame_5.png new file mode 100644 index 0000000000..1d8763863e Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_TALK/frame_5.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_TALK/frame_6.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_TALK/frame_6.png new file mode 100644 index 0000000000..dd9a145746 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_TALK/frame_6.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_TALK/frame_7.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_TALK/frame_7.png new file mode 100644 index 0000000000..3ca8d24bcc Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_TALK/frame_7.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_TALK/frame_8.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_TALK/frame_8.png new file mode 100644 index 0000000000..84897f6a9e Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_TALK/frame_8.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_TALK/frame_9.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_TALK/frame_9.png new file mode 100644 index 0000000000..e216a7215b Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_TALK/frame_9.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_TALK/meta.txt b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_TALK/meta.txt new file mode 100644 index 0000000000..e92e595306 --- /dev/null +++ b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_TALK/meta.txt @@ -0,0 +1,14 @@ +Filetype: Flipper Animation +Version: 1 + +Width: 128 +Height: 64 +Passive frames: 18 +Active frames: 0 +Frames order: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 +Active cycles: 0 +Frame rate: 4 +Duration: 3600 +Active cooldown: 0 + +Bubble slots: 0 diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_WAVE/frame_0.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_WAVE/frame_0.png new file mode 100644 index 0000000000..5a984b3fea Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_WAVE/frame_0.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_WAVE/frame_1.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_WAVE/frame_1.png new file mode 100644 index 0000000000..464320e1b3 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_WAVE/frame_1.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_WAVE/frame_10.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_WAVE/frame_10.png new file mode 100644 index 0000000000..e555bd8255 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_WAVE/frame_10.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_WAVE/frame_11.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_WAVE/frame_11.png new file mode 100644 index 0000000000..f321a49cc0 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_WAVE/frame_11.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_WAVE/frame_12.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_WAVE/frame_12.png new file mode 100644 index 0000000000..26514e26c6 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_WAVE/frame_12.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_WAVE/frame_13.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_WAVE/frame_13.png new file mode 100644 index 0000000000..f25efd6bc3 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_WAVE/frame_13.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_WAVE/frame_14.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_WAVE/frame_14.png new file mode 100644 index 0000000000..c6d8d757bf Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_WAVE/frame_14.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_WAVE/frame_15.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_WAVE/frame_15.png new file mode 100644 index 0000000000..63cba43031 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_WAVE/frame_15.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_WAVE/frame_2.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_WAVE/frame_2.png new file mode 100644 index 0000000000..9e4f4f6cdc Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_WAVE/frame_2.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_WAVE/frame_3.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_WAVE/frame_3.png new file mode 100644 index 0000000000..3f86d2d222 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_WAVE/frame_3.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_WAVE/frame_4.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_WAVE/frame_4.png new file mode 100644 index 0000000000..6c5e9d3aa1 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_WAVE/frame_4.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_WAVE/frame_5.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_WAVE/frame_5.png new file mode 100644 index 0000000000..99c1870503 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_WAVE/frame_5.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_WAVE/frame_6.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_WAVE/frame_6.png new file mode 100644 index 0000000000..7ce194f3c0 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_WAVE/frame_6.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_WAVE/frame_7.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_WAVE/frame_7.png new file mode 100644 index 0000000000..977937e265 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_WAVE/frame_7.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_WAVE/frame_8.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_WAVE/frame_8.png new file mode 100644 index 0000000000..fdb03d1813 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_WAVE/frame_8.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_WAVE/frame_9.png b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_WAVE/frame_9.png new file mode 100644 index 0000000000..f2f74aa555 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_WAVE/frame_9.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_WAVE/meta.txt b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_WAVE/meta.txt new file mode 100644 index 0000000000..55dd3ae55f --- /dev/null +++ b/assets/dolphin/custom/WatchDogs/Anims/DEDSEC_WAVE/meta.txt @@ -0,0 +1,14 @@ +Filetype: Flipper Animation +Version: 1 + +Width: 128 +Height: 64 +Passive frames: 16 +Active frames: 0 +Frames order: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 +Active cycles: 0 +Frame rate: 7 +Duration: 3600 +Active cooldown: 0 + +Bubble slots: 0 diff --git a/assets/dolphin/custom/WatchDogs/Anims/FINGER/frame_0.png b/assets/dolphin/custom/WatchDogs/Anims/FINGER/frame_0.png new file mode 100644 index 0000000000..31e214233a Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/FINGER/frame_0.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/FINGER/frame_1.png b/assets/dolphin/custom/WatchDogs/Anims/FINGER/frame_1.png new file mode 100644 index 0000000000..9aefc5ccd4 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/FINGER/frame_1.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/FINGER/frame_2.png b/assets/dolphin/custom/WatchDogs/Anims/FINGER/frame_2.png new file mode 100644 index 0000000000..9a33e7cb5b Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/FINGER/frame_2.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/FINGER/frame_3.png b/assets/dolphin/custom/WatchDogs/Anims/FINGER/frame_3.png new file mode 100644 index 0000000000..330d927851 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/FINGER/frame_3.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/FINGER/meta.txt b/assets/dolphin/custom/WatchDogs/Anims/FINGER/meta.txt new file mode 100644 index 0000000000..118db3cbed --- /dev/null +++ b/assets/dolphin/custom/WatchDogs/Anims/FINGER/meta.txt @@ -0,0 +1,14 @@ +Filetype: Flipper Animation +Version: 1 + +Width: 128 +Height: 64 +Passive frames: 6 +Active frames: 0 +Frames order: 0 1 2 3 2 3 +Active cycles: 0 +Frame rate: 2 +Duration: 3600 +Active cooldown: 0 + +Bubble slots: 0 diff --git a/assets/dolphin/custom/WatchDogs/Anims/GUNS_CAR/frame_0.png b/assets/dolphin/custom/WatchDogs/Anims/GUNS_CAR/frame_0.png new file mode 100644 index 0000000000..1de1eb7999 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/GUNS_CAR/frame_0.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/GUNS_CAR/frame_1.png b/assets/dolphin/custom/WatchDogs/Anims/GUNS_CAR/frame_1.png new file mode 100644 index 0000000000..e371e09f89 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/GUNS_CAR/frame_1.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/GUNS_CAR/frame_10.png b/assets/dolphin/custom/WatchDogs/Anims/GUNS_CAR/frame_10.png new file mode 100644 index 0000000000..d6d347e91d Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/GUNS_CAR/frame_10.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/GUNS_CAR/frame_11.png b/assets/dolphin/custom/WatchDogs/Anims/GUNS_CAR/frame_11.png new file mode 100644 index 0000000000..db64d4360e Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/GUNS_CAR/frame_11.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/GUNS_CAR/frame_12.png b/assets/dolphin/custom/WatchDogs/Anims/GUNS_CAR/frame_12.png new file mode 100644 index 0000000000..ed2d5a88fd Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/GUNS_CAR/frame_12.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/GUNS_CAR/frame_13.png b/assets/dolphin/custom/WatchDogs/Anims/GUNS_CAR/frame_13.png new file mode 100644 index 0000000000..6ad3e53d2a Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/GUNS_CAR/frame_13.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/GUNS_CAR/frame_14.png b/assets/dolphin/custom/WatchDogs/Anims/GUNS_CAR/frame_14.png new file mode 100644 index 0000000000..4c3904deee Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/GUNS_CAR/frame_14.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/GUNS_CAR/frame_15.png b/assets/dolphin/custom/WatchDogs/Anims/GUNS_CAR/frame_15.png new file mode 100644 index 0000000000..29e4ebc96a Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/GUNS_CAR/frame_15.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/GUNS_CAR/frame_16.png b/assets/dolphin/custom/WatchDogs/Anims/GUNS_CAR/frame_16.png new file mode 100644 index 0000000000..933540182d Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/GUNS_CAR/frame_16.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/GUNS_CAR/frame_17.png b/assets/dolphin/custom/WatchDogs/Anims/GUNS_CAR/frame_17.png new file mode 100644 index 0000000000..3b2c6005cf Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/GUNS_CAR/frame_17.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/GUNS_CAR/frame_18.png b/assets/dolphin/custom/WatchDogs/Anims/GUNS_CAR/frame_18.png new file mode 100644 index 0000000000..a77629d715 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/GUNS_CAR/frame_18.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/GUNS_CAR/frame_19.png b/assets/dolphin/custom/WatchDogs/Anims/GUNS_CAR/frame_19.png new file mode 100644 index 0000000000..1d2bfa9ec7 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/GUNS_CAR/frame_19.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/GUNS_CAR/frame_2.png b/assets/dolphin/custom/WatchDogs/Anims/GUNS_CAR/frame_2.png new file mode 100644 index 0000000000..d6c5135f7f Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/GUNS_CAR/frame_2.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/GUNS_CAR/frame_20.png b/assets/dolphin/custom/WatchDogs/Anims/GUNS_CAR/frame_20.png new file mode 100644 index 0000000000..adc99f125f Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/GUNS_CAR/frame_20.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/GUNS_CAR/frame_21.png b/assets/dolphin/custom/WatchDogs/Anims/GUNS_CAR/frame_21.png new file mode 100644 index 0000000000..8e2359a9cb Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/GUNS_CAR/frame_21.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/GUNS_CAR/frame_3.png b/assets/dolphin/custom/WatchDogs/Anims/GUNS_CAR/frame_3.png new file mode 100644 index 0000000000..a7523702b8 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/GUNS_CAR/frame_3.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/GUNS_CAR/frame_4.png b/assets/dolphin/custom/WatchDogs/Anims/GUNS_CAR/frame_4.png new file mode 100644 index 0000000000..a9db6a3ec4 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/GUNS_CAR/frame_4.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/GUNS_CAR/frame_5.png b/assets/dolphin/custom/WatchDogs/Anims/GUNS_CAR/frame_5.png new file mode 100644 index 0000000000..bc2c2bfa5f Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/GUNS_CAR/frame_5.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/GUNS_CAR/frame_6.png b/assets/dolphin/custom/WatchDogs/Anims/GUNS_CAR/frame_6.png new file mode 100644 index 0000000000..1d3844ba21 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/GUNS_CAR/frame_6.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/GUNS_CAR/frame_7.png b/assets/dolphin/custom/WatchDogs/Anims/GUNS_CAR/frame_7.png new file mode 100644 index 0000000000..d4891052dc Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/GUNS_CAR/frame_7.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/GUNS_CAR/frame_8.png b/assets/dolphin/custom/WatchDogs/Anims/GUNS_CAR/frame_8.png new file mode 100644 index 0000000000..60de906f26 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/GUNS_CAR/frame_8.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/GUNS_CAR/frame_9.png b/assets/dolphin/custom/WatchDogs/Anims/GUNS_CAR/frame_9.png new file mode 100644 index 0000000000..f2cb5351d6 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/GUNS_CAR/frame_9.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/GUNS_CAR/meta.txt b/assets/dolphin/custom/WatchDogs/Anims/GUNS_CAR/meta.txt new file mode 100644 index 0000000000..8fe58cec3f --- /dev/null +++ b/assets/dolphin/custom/WatchDogs/Anims/GUNS_CAR/meta.txt @@ -0,0 +1,14 @@ +Filetype: Flipper Animation +Version: 1 + +Width: 128 +Height: 64 +Passive frames: 22 +Active frames: 0 +Frames order: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 +Active cycles: 0 +Frame rate: 4 +Duration: 3600 +Active cooldown: 0 + +Bubble slots: 0 diff --git a/assets/dolphin/custom/WatchDogs/Anims/HANDS/frame_0.png b/assets/dolphin/custom/WatchDogs/Anims/HANDS/frame_0.png new file mode 100644 index 0000000000..80a6862347 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/HANDS/frame_0.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/HANDS/frame_1.png b/assets/dolphin/custom/WatchDogs/Anims/HANDS/frame_1.png new file mode 100644 index 0000000000..a7ed6a7135 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/HANDS/frame_1.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/HANDS/frame_2.png b/assets/dolphin/custom/WatchDogs/Anims/HANDS/frame_2.png new file mode 100644 index 0000000000..f07808ca10 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/HANDS/frame_2.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/HANDS/frame_3.png b/assets/dolphin/custom/WatchDogs/Anims/HANDS/frame_3.png new file mode 100644 index 0000000000..68001742ec Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/HANDS/frame_3.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/HANDS/frame_4.png b/assets/dolphin/custom/WatchDogs/Anims/HANDS/frame_4.png new file mode 100644 index 0000000000..f22c71e4f8 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/HANDS/frame_4.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/HANDS/frame_5.png b/assets/dolphin/custom/WatchDogs/Anims/HANDS/frame_5.png new file mode 100644 index 0000000000..1626ec7eb0 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/HANDS/frame_5.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/HANDS/frame_6.png b/assets/dolphin/custom/WatchDogs/Anims/HANDS/frame_6.png new file mode 100644 index 0000000000..d2fe2859de Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/HANDS/frame_6.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/HANDS/meta.txt b/assets/dolphin/custom/WatchDogs/Anims/HANDS/meta.txt new file mode 100644 index 0000000000..f83c9071bf --- /dev/null +++ b/assets/dolphin/custom/WatchDogs/Anims/HANDS/meta.txt @@ -0,0 +1,14 @@ +Filetype: Flipper Animation +Version: 1 + +Width: 128 +Height: 64 +Passive frames: 12 +Active frames: 0 +Frames order: 0 1 2 3 4 5 6 5 4 3 2 1 +Active cycles: 0 +Frame rate: 4 +Duration: 3600 +Active cooldown: 0 + +Bubble slots: 0 diff --git a/assets/dolphin/custom/WatchDogs/Anims/JOIN_US/frame_0.png b/assets/dolphin/custom/WatchDogs/Anims/JOIN_US/frame_0.png new file mode 100644 index 0000000000..e9ec089bd7 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/JOIN_US/frame_0.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/JOIN_US/frame_1.png b/assets/dolphin/custom/WatchDogs/Anims/JOIN_US/frame_1.png new file mode 100644 index 0000000000..d63fb1a621 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/JOIN_US/frame_1.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/JOIN_US/meta.txt b/assets/dolphin/custom/WatchDogs/Anims/JOIN_US/meta.txt new file mode 100644 index 0000000000..10961ac36a --- /dev/null +++ b/assets/dolphin/custom/WatchDogs/Anims/JOIN_US/meta.txt @@ -0,0 +1,14 @@ +Filetype: Flipper Animation +Version: 1 + +Width: 128 +Height: 64 +Passive frames: 2 +Active frames: 0 +Frames order: 0 1 +Active cycles: 0 +Frame rate: 2 +Duration: 3600 +Active cooldown: 0 + +Bubble slots: 0 diff --git a/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_0.png b/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_0.png new file mode 100644 index 0000000000..3c5da572b0 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_0.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_1.png b/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_1.png new file mode 100644 index 0000000000..1521a40744 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_1.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_10.png b/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_10.png new file mode 100644 index 0000000000..8ceef48df8 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_10.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_11.png b/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_11.png new file mode 100644 index 0000000000..0d0c9ebd09 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_11.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_12.png b/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_12.png new file mode 100644 index 0000000000..81d1e7de48 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_12.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_13.png b/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_13.png new file mode 100644 index 0000000000..d71fafd91b Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_13.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_14.png b/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_14.png new file mode 100644 index 0000000000..db3c1e13bd Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_14.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_15.png b/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_15.png new file mode 100644 index 0000000000..349c118e26 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_15.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_16.png b/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_16.png new file mode 100644 index 0000000000..d9f43514d2 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_16.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_17.png b/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_17.png new file mode 100644 index 0000000000..27de431a8d Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_17.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_18.png b/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_18.png new file mode 100644 index 0000000000..dfbffeccf1 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_18.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_19.png b/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_19.png new file mode 100644 index 0000000000..d2c9252ca0 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_19.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_2.png b/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_2.png new file mode 100644 index 0000000000..c0ac00aeb5 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_2.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_20.png b/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_20.png new file mode 100644 index 0000000000..d2b1ed935f Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_20.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_21.png b/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_21.png new file mode 100644 index 0000000000..da83a3664f Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_21.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_22.png b/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_22.png new file mode 100644 index 0000000000..3ddb22e97b Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_22.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_23.png b/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_23.png new file mode 100644 index 0000000000..1c87707372 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_23.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_24.png b/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_24.png new file mode 100644 index 0000000000..1521a40744 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_24.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_25.png b/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_25.png new file mode 100644 index 0000000000..7fd19087cf Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_25.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_26.png b/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_26.png new file mode 100644 index 0000000000..1521a40744 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_26.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_27.png b/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_27.png new file mode 100644 index 0000000000..01b1cb1e02 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_27.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_28.png b/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_28.png new file mode 100644 index 0000000000..534604c261 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_28.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_29.png b/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_29.png new file mode 100644 index 0000000000..1521a40744 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_29.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_3.png b/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_3.png new file mode 100644 index 0000000000..7aacdfc57f Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_3.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_30.png b/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_30.png new file mode 100644 index 0000000000..1521a40744 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_30.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_4.png b/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_4.png new file mode 100644 index 0000000000..1521a40744 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_4.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_5.png b/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_5.png new file mode 100644 index 0000000000..38566222f6 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_5.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_6.png b/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_6.png new file mode 100644 index 0000000000..b92ba5c745 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_6.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_7.png b/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_7.png new file mode 100644 index 0000000000..71095643ba Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_7.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_8.png b/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_8.png new file mode 100644 index 0000000000..1c8db93f4c Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_8.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_9.png b/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_9.png new file mode 100644 index 0000000000..eef209b336 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/frame_9.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/meta.txt b/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/meta.txt new file mode 100644 index 0000000000..305463c192 --- /dev/null +++ b/assets/dolphin/custom/WatchDogs/Anims/LOGO_WD2/meta.txt @@ -0,0 +1,14 @@ +Filetype: Flipper Animation +Version: 1 + +Width: 128 +Height: 64 +Passive frames: 31 +Active frames: 0 +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 +Active cycles: 0 +Frame rate: 4 +Duration: 3600 +Active cooldown: 0 + +Bubble slots: 0 diff --git a/assets/dolphin/custom/WatchDogs/Anims/MARCUS/frame_0.png b/assets/dolphin/custom/WatchDogs/Anims/MARCUS/frame_0.png new file mode 100644 index 0000000000..a9d12865cb Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/MARCUS/frame_0.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/MARCUS/frame_1.png b/assets/dolphin/custom/WatchDogs/Anims/MARCUS/frame_1.png new file mode 100644 index 0000000000..f095bc1b10 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/MARCUS/frame_1.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/MARCUS/frame_10.png b/assets/dolphin/custom/WatchDogs/Anims/MARCUS/frame_10.png new file mode 100644 index 0000000000..cf3985ed86 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/MARCUS/frame_10.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/MARCUS/frame_11.png b/assets/dolphin/custom/WatchDogs/Anims/MARCUS/frame_11.png new file mode 100644 index 0000000000..dadb73cf08 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/MARCUS/frame_11.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/MARCUS/frame_12.png b/assets/dolphin/custom/WatchDogs/Anims/MARCUS/frame_12.png new file mode 100644 index 0000000000..926726e107 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/MARCUS/frame_12.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/MARCUS/frame_13.png b/assets/dolphin/custom/WatchDogs/Anims/MARCUS/frame_13.png new file mode 100644 index 0000000000..94aee738bf Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/MARCUS/frame_13.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/MARCUS/frame_14.png b/assets/dolphin/custom/WatchDogs/Anims/MARCUS/frame_14.png new file mode 100644 index 0000000000..ace6e41099 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/MARCUS/frame_14.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/MARCUS/frame_15.png b/assets/dolphin/custom/WatchDogs/Anims/MARCUS/frame_15.png new file mode 100644 index 0000000000..7c8478b22c Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/MARCUS/frame_15.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/MARCUS/frame_16.png b/assets/dolphin/custom/WatchDogs/Anims/MARCUS/frame_16.png new file mode 100644 index 0000000000..ab4fed5611 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/MARCUS/frame_16.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/MARCUS/frame_17.png b/assets/dolphin/custom/WatchDogs/Anims/MARCUS/frame_17.png new file mode 100644 index 0000000000..d00c23db4b Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/MARCUS/frame_17.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/MARCUS/frame_18.png b/assets/dolphin/custom/WatchDogs/Anims/MARCUS/frame_18.png new file mode 100644 index 0000000000..b7d0fd275f Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/MARCUS/frame_18.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/MARCUS/frame_19.png b/assets/dolphin/custom/WatchDogs/Anims/MARCUS/frame_19.png new file mode 100644 index 0000000000..e1bbfce92d Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/MARCUS/frame_19.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/MARCUS/frame_2.png b/assets/dolphin/custom/WatchDogs/Anims/MARCUS/frame_2.png new file mode 100644 index 0000000000..0414056941 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/MARCUS/frame_2.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/MARCUS/frame_20.png b/assets/dolphin/custom/WatchDogs/Anims/MARCUS/frame_20.png new file mode 100644 index 0000000000..c40f702406 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/MARCUS/frame_20.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/MARCUS/frame_21.png b/assets/dolphin/custom/WatchDogs/Anims/MARCUS/frame_21.png new file mode 100644 index 0000000000..c354815327 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/MARCUS/frame_21.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/MARCUS/frame_22.png b/assets/dolphin/custom/WatchDogs/Anims/MARCUS/frame_22.png new file mode 100644 index 0000000000..c641b77bfd Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/MARCUS/frame_22.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/MARCUS/frame_23.png b/assets/dolphin/custom/WatchDogs/Anims/MARCUS/frame_23.png new file mode 100644 index 0000000000..4fd396da22 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/MARCUS/frame_23.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/MARCUS/frame_3.png b/assets/dolphin/custom/WatchDogs/Anims/MARCUS/frame_3.png new file mode 100644 index 0000000000..b197057549 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/MARCUS/frame_3.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/MARCUS/frame_4.png b/assets/dolphin/custom/WatchDogs/Anims/MARCUS/frame_4.png new file mode 100644 index 0000000000..f78254d1ed Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/MARCUS/frame_4.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/MARCUS/frame_5.png b/assets/dolphin/custom/WatchDogs/Anims/MARCUS/frame_5.png new file mode 100644 index 0000000000..cd9f29873a Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/MARCUS/frame_5.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/MARCUS/frame_6.png b/assets/dolphin/custom/WatchDogs/Anims/MARCUS/frame_6.png new file mode 100644 index 0000000000..0389283591 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/MARCUS/frame_6.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/MARCUS/frame_7.png b/assets/dolphin/custom/WatchDogs/Anims/MARCUS/frame_7.png new file mode 100644 index 0000000000..8b107952fd Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/MARCUS/frame_7.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/MARCUS/frame_8.png b/assets/dolphin/custom/WatchDogs/Anims/MARCUS/frame_8.png new file mode 100644 index 0000000000..97e0c5d215 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/MARCUS/frame_8.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/MARCUS/frame_9.png b/assets/dolphin/custom/WatchDogs/Anims/MARCUS/frame_9.png new file mode 100644 index 0000000000..e40ac44f7c Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/MARCUS/frame_9.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/MARCUS/meta.txt b/assets/dolphin/custom/WatchDogs/Anims/MARCUS/meta.txt new file mode 100644 index 0000000000..81cc6c7d92 --- /dev/null +++ b/assets/dolphin/custom/WatchDogs/Anims/MARCUS/meta.txt @@ -0,0 +1,14 @@ +Filetype: Flipper Animation +Version: 1 + +Width: 128 +Height: 64 +Passive frames: 24 +Active frames: 0 +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 +Active cycles: 0 +Frame rate: 4 +Duration: 3600 +Active cooldown: 0 + +Bubble slots: 0 diff --git a/assets/dolphin/custom/WatchDogs/Anims/MUMMY/frame_0.png b/assets/dolphin/custom/WatchDogs/Anims/MUMMY/frame_0.png new file mode 100644 index 0000000000..57e428ae1c Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/MUMMY/frame_0.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/MUMMY/frame_1.png b/assets/dolphin/custom/WatchDogs/Anims/MUMMY/frame_1.png new file mode 100644 index 0000000000..455d14230e Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/MUMMY/frame_1.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/MUMMY/frame_2.png b/assets/dolphin/custom/WatchDogs/Anims/MUMMY/frame_2.png new file mode 100644 index 0000000000..33f13a62ce Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/MUMMY/frame_2.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/MUMMY/frame_3.png b/assets/dolphin/custom/WatchDogs/Anims/MUMMY/frame_3.png new file mode 100644 index 0000000000..b43a976645 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/MUMMY/frame_3.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/MUMMY/meta.txt b/assets/dolphin/custom/WatchDogs/Anims/MUMMY/meta.txt new file mode 100644 index 0000000000..1ede667459 --- /dev/null +++ b/assets/dolphin/custom/WatchDogs/Anims/MUMMY/meta.txt @@ -0,0 +1,23 @@ +Filetype: Flipper Animation +Version: 1 + +Width: 128 +Height: 64 +Passive frames: 5 +Active frames: 4 +Frames order: 2 0 1 3 0 2 3 2 3 +Active cycles: 2 +Frame rate: 2 +Duration: 3600 +Active cooldown: 1 + +Bubble slots: 1 + +Slot: 0 +X: 27 +Y: 24 +Text: AARGH! +AlignH: Right +AlignV: Center +StartFrame: 6 +EndFrame: 9 diff --git a/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_0.png b/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_0.png new file mode 100644 index 0000000000..0e31210491 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_0.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_1.png b/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_1.png new file mode 100644 index 0000000000..af05489ac5 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_1.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_10.png b/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_10.png new file mode 100644 index 0000000000..e51864e6cd Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_10.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_11.png b/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_11.png new file mode 100644 index 0000000000..ff85eb9d8e Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_11.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_12.png b/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_12.png new file mode 100644 index 0000000000..d271655721 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_12.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_13.png b/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_13.png new file mode 100644 index 0000000000..1dfd3ca90c Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_13.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_14.png b/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_14.png new file mode 100644 index 0000000000..77c31b2960 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_14.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_15.png b/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_15.png new file mode 100644 index 0000000000..f6b9e83b90 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_15.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_16.png b/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_16.png new file mode 100644 index 0000000000..1af1e42b22 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_16.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_17.png b/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_17.png new file mode 100644 index 0000000000..5316af01f2 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_17.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_18.png b/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_18.png new file mode 100644 index 0000000000..b70af3eee8 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_18.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_19.png b/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_19.png new file mode 100644 index 0000000000..49fe9749a1 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_19.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_2.png b/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_2.png new file mode 100644 index 0000000000..4c00f5c336 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_2.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_20.png b/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_20.png new file mode 100644 index 0000000000..82343d600d Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_20.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_21.png b/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_21.png new file mode 100644 index 0000000000..8de989381e Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_21.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_22.png b/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_22.png new file mode 100644 index 0000000000..4e66988e38 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_22.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_23.png b/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_23.png new file mode 100644 index 0000000000..54e58d1ee0 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_23.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_24.png b/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_24.png new file mode 100644 index 0000000000..89387f71e0 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_24.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_25.png b/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_25.png new file mode 100644 index 0000000000..7a678691a7 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_25.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_26.png b/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_26.png new file mode 100644 index 0000000000..a81a51793a Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_26.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_27.png b/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_27.png new file mode 100644 index 0000000000..6abea9a9a9 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_27.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_28.png b/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_28.png new file mode 100644 index 0000000000..e9810705c9 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_28.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_29.png b/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_29.png new file mode 100644 index 0000000000..37bc0de0f9 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_29.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_3.png b/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_3.png new file mode 100644 index 0000000000..b66d9e93dd Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_3.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_30.png b/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_30.png new file mode 100644 index 0000000000..8a11e4e6b3 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_30.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_31.png b/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_31.png new file mode 100644 index 0000000000..5c4971b0d2 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_31.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_4.png b/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_4.png new file mode 100644 index 0000000000..18cf2906e6 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_4.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_5.png b/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_5.png new file mode 100644 index 0000000000..30c9ddef4b Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_5.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_6.png b/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_6.png new file mode 100644 index 0000000000..b276b75054 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_6.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_7.png b/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_7.png new file mode 100644 index 0000000000..d590c76cd7 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_7.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_8.png b/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_8.png new file mode 100644 index 0000000000..18f5c86f3b Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_8.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_9.png b/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_9.png new file mode 100644 index 0000000000..fcfd843157 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/REAPER/frame_9.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/REAPER/meta.txt b/assets/dolphin/custom/WatchDogs/Anims/REAPER/meta.txt new file mode 100644 index 0000000000..64a5c94655 --- /dev/null +++ b/assets/dolphin/custom/WatchDogs/Anims/REAPER/meta.txt @@ -0,0 +1,14 @@ +Filetype: Flipper Animation +Version: 1 + +Width: 128 +Height: 64 +Passive frames: 32 +Active frames: 0 +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 +Active cycles: 0 +Frame rate: 5 +Duration: 3600 +Active cooldown: 0 + +Bubble slots: 0 diff --git a/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_0.png b/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_0.png new file mode 100644 index 0000000000..86d80b1f40 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_0.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_1.png b/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_1.png new file mode 100644 index 0000000000..8164c90df8 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_1.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_10.png b/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_10.png new file mode 100644 index 0000000000..5cbb4139fc Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_10.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_11.png b/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_11.png new file mode 100644 index 0000000000..2305adca14 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_11.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_12.png b/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_12.png new file mode 100644 index 0000000000..380d9f8090 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_12.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_13.png b/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_13.png new file mode 100644 index 0000000000..5de21d181a Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_13.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_14.png b/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_14.png new file mode 100644 index 0000000000..d32777df33 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_14.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_15.png b/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_15.png new file mode 100644 index 0000000000..29d080c25e Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_15.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_16.png b/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_16.png new file mode 100644 index 0000000000..cc95da49ae Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_16.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_17.png b/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_17.png new file mode 100644 index 0000000000..13e31d1cb7 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_17.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_18.png b/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_18.png new file mode 100644 index 0000000000..8ebbe0775f Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_18.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_19.png b/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_19.png new file mode 100644 index 0000000000..a0f5ff6297 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_19.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_2.png b/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_2.png new file mode 100644 index 0000000000..33ce3a93ee Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_2.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_20.png b/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_20.png new file mode 100644 index 0000000000..06e3cbd27b Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_20.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_21.png b/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_21.png new file mode 100644 index 0000000000..0471a44605 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_21.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_22.png b/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_22.png new file mode 100644 index 0000000000..88af208cb2 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_22.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_23.png b/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_23.png new file mode 100644 index 0000000000..77cf21a28e Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_23.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_24.png b/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_24.png new file mode 100644 index 0000000000..1d6a455752 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_24.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_25.png b/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_25.png new file mode 100644 index 0000000000..a62acdaf40 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_25.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_26.png b/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_26.png new file mode 100644 index 0000000000..d3aeb6795a Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_26.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_27.png b/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_27.png new file mode 100644 index 0000000000..2f80a1e601 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_27.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_28.png b/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_28.png new file mode 100644 index 0000000000..6fe35e9cec Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_28.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_29.png b/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_29.png new file mode 100644 index 0000000000..99a8eb22d8 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_29.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_3.png b/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_3.png new file mode 100644 index 0000000000..337f25fcfb Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_3.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_30.png b/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_30.png new file mode 100644 index 0000000000..a39e6cd794 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_30.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_31.png b/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_31.png new file mode 100644 index 0000000000..16249a86e3 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_31.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_32.png b/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_32.png new file mode 100644 index 0000000000..a12091cae2 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_32.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_33.png b/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_33.png new file mode 100644 index 0000000000..7b5c0c3bb7 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_33.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_34.png b/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_34.png new file mode 100644 index 0000000000..0347c7ecc1 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_34.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_35.png b/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_35.png new file mode 100644 index 0000000000..50c5ca8702 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_35.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_36.png b/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_36.png new file mode 100644 index 0000000000..96257a93c4 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_36.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_37.png b/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_37.png new file mode 100644 index 0000000000..711adeeca8 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_37.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_38.png b/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_38.png new file mode 100644 index 0000000000..66c056b4c5 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_38.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_39.png b/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_39.png new file mode 100644 index 0000000000..471df7ab5e Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_39.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_4.png b/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_4.png new file mode 100644 index 0000000000..c9c087812a Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_4.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_40.png b/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_40.png new file mode 100644 index 0000000000..1e55a33045 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_40.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_41.png b/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_41.png new file mode 100644 index 0000000000..14e07d1d7e Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_41.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_5.png b/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_5.png new file mode 100644 index 0000000000..1b8ced8cc5 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_5.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_6.png b/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_6.png new file mode 100644 index 0000000000..510d4d9ad8 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_6.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_7.png b/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_7.png new file mode 100644 index 0000000000..11c9c86248 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_7.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_8.png b/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_8.png new file mode 100644 index 0000000000..857c42833e Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_8.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_9.png b/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_9.png new file mode 100644 index 0000000000..553b633990 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/frame_9.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/meta.txt b/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/meta.txt new file mode 100644 index 0000000000..d3a51de2f1 --- /dev/null +++ b/assets/dolphin/custom/WatchDogs/Anims/REAPER_ALT/meta.txt @@ -0,0 +1,14 @@ +Filetype: Flipper Animation +Version: 1 + +Width: 128 +Height: 64 +Passive frames: 28 +Active frames: 0 +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 +Active cycles: 0 +Frame rate: 4 +Duration: 3600 +Active cooldown: 0 + +Bubble slots: 0 diff --git a/assets/dolphin/custom/WatchDogs/Anims/SKULL/frame_0.png b/assets/dolphin/custom/WatchDogs/Anims/SKULL/frame_0.png new file mode 100644 index 0000000000..aab8f0e4bf Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/SKULL/frame_0.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/SKULL/frame_1.png b/assets/dolphin/custom/WatchDogs/Anims/SKULL/frame_1.png new file mode 100644 index 0000000000..4449f9cc38 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/SKULL/frame_1.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/SKULL/frame_10.png b/assets/dolphin/custom/WatchDogs/Anims/SKULL/frame_10.png new file mode 100644 index 0000000000..fda4a43fdc Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/SKULL/frame_10.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/SKULL/frame_11.png b/assets/dolphin/custom/WatchDogs/Anims/SKULL/frame_11.png new file mode 100644 index 0000000000..52be57e775 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/SKULL/frame_11.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/SKULL/frame_12.png b/assets/dolphin/custom/WatchDogs/Anims/SKULL/frame_12.png new file mode 100644 index 0000000000..e14579b856 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/SKULL/frame_12.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/SKULL/frame_13.png b/assets/dolphin/custom/WatchDogs/Anims/SKULL/frame_13.png new file mode 100644 index 0000000000..cf7f45963a Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/SKULL/frame_13.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/SKULL/frame_14.png b/assets/dolphin/custom/WatchDogs/Anims/SKULL/frame_14.png new file mode 100644 index 0000000000..73dee0d3d8 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/SKULL/frame_14.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/SKULL/frame_15.png b/assets/dolphin/custom/WatchDogs/Anims/SKULL/frame_15.png new file mode 100644 index 0000000000..b08a68f51a Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/SKULL/frame_15.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/SKULL/frame_16.png b/assets/dolphin/custom/WatchDogs/Anims/SKULL/frame_16.png new file mode 100644 index 0000000000..1f005ee274 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/SKULL/frame_16.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/SKULL/frame_17.png b/assets/dolphin/custom/WatchDogs/Anims/SKULL/frame_17.png new file mode 100644 index 0000000000..057ad3a598 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/SKULL/frame_17.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/SKULL/frame_18.png b/assets/dolphin/custom/WatchDogs/Anims/SKULL/frame_18.png new file mode 100644 index 0000000000..b2fe331bf4 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/SKULL/frame_18.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/SKULL/frame_19.png b/assets/dolphin/custom/WatchDogs/Anims/SKULL/frame_19.png new file mode 100644 index 0000000000..cdf1601d36 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/SKULL/frame_19.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/SKULL/frame_2.png b/assets/dolphin/custom/WatchDogs/Anims/SKULL/frame_2.png new file mode 100644 index 0000000000..6d647bc820 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/SKULL/frame_2.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/SKULL/frame_20.png b/assets/dolphin/custom/WatchDogs/Anims/SKULL/frame_20.png new file mode 100644 index 0000000000..7cf04e830d Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/SKULL/frame_20.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/SKULL/frame_21.png b/assets/dolphin/custom/WatchDogs/Anims/SKULL/frame_21.png new file mode 100644 index 0000000000..e5e747ee93 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/SKULL/frame_21.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/SKULL/frame_22.png b/assets/dolphin/custom/WatchDogs/Anims/SKULL/frame_22.png new file mode 100644 index 0000000000..a48d68767b Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/SKULL/frame_22.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/SKULL/frame_23.png b/assets/dolphin/custom/WatchDogs/Anims/SKULL/frame_23.png new file mode 100644 index 0000000000..6f3040f193 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/SKULL/frame_23.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/SKULL/frame_24.png b/assets/dolphin/custom/WatchDogs/Anims/SKULL/frame_24.png new file mode 100644 index 0000000000..c1cb28c3d4 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/SKULL/frame_24.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/SKULL/frame_25.png b/assets/dolphin/custom/WatchDogs/Anims/SKULL/frame_25.png new file mode 100644 index 0000000000..cda5ab4b5a Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/SKULL/frame_25.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/SKULL/frame_26.png b/assets/dolphin/custom/WatchDogs/Anims/SKULL/frame_26.png new file mode 100644 index 0000000000..a6d932c752 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/SKULL/frame_26.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/SKULL/frame_3.png b/assets/dolphin/custom/WatchDogs/Anims/SKULL/frame_3.png new file mode 100644 index 0000000000..569095f235 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/SKULL/frame_3.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/SKULL/frame_4.png b/assets/dolphin/custom/WatchDogs/Anims/SKULL/frame_4.png new file mode 100644 index 0000000000..ccef8cefcb Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/SKULL/frame_4.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/SKULL/frame_5.png b/assets/dolphin/custom/WatchDogs/Anims/SKULL/frame_5.png new file mode 100644 index 0000000000..5281fc38f5 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/SKULL/frame_5.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/SKULL/frame_6.png b/assets/dolphin/custom/WatchDogs/Anims/SKULL/frame_6.png new file mode 100644 index 0000000000..f89551530d Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/SKULL/frame_6.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/SKULL/frame_7.png b/assets/dolphin/custom/WatchDogs/Anims/SKULL/frame_7.png new file mode 100644 index 0000000000..ef696f4671 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/SKULL/frame_7.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/SKULL/frame_8.png b/assets/dolphin/custom/WatchDogs/Anims/SKULL/frame_8.png new file mode 100644 index 0000000000..90579348ae Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/SKULL/frame_8.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/SKULL/frame_9.png b/assets/dolphin/custom/WatchDogs/Anims/SKULL/frame_9.png new file mode 100644 index 0000000000..389793bae3 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/SKULL/frame_9.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/SKULL/meta.txt b/assets/dolphin/custom/WatchDogs/Anims/SKULL/meta.txt new file mode 100644 index 0000000000..1ca66ff130 --- /dev/null +++ b/assets/dolphin/custom/WatchDogs/Anims/SKULL/meta.txt @@ -0,0 +1,14 @@ +Filetype: Flipper Animation +Version: 1 + +Width: 128 +Height: 64 +Passive frames: 27 +Active frames: 0 +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 +Active cycles: 0 +Frame rate: 4 +Duration: 3600 +Active cooldown: 0 + +Bubble slots: 0 diff --git a/assets/dolphin/custom/WatchDogs/Anims/SKULL_SPIN/frame_0.png b/assets/dolphin/custom/WatchDogs/Anims/SKULL_SPIN/frame_0.png new file mode 100644 index 0000000000..da0bbeb09c Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/SKULL_SPIN/frame_0.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/SKULL_SPIN/frame_1.png b/assets/dolphin/custom/WatchDogs/Anims/SKULL_SPIN/frame_1.png new file mode 100644 index 0000000000..1b992e98ed Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/SKULL_SPIN/frame_1.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/SKULL_SPIN/frame_10.png b/assets/dolphin/custom/WatchDogs/Anims/SKULL_SPIN/frame_10.png new file mode 100644 index 0000000000..ba1662e216 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/SKULL_SPIN/frame_10.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/SKULL_SPIN/frame_11.png b/assets/dolphin/custom/WatchDogs/Anims/SKULL_SPIN/frame_11.png new file mode 100644 index 0000000000..01726538f1 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/SKULL_SPIN/frame_11.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/SKULL_SPIN/frame_12.png b/assets/dolphin/custom/WatchDogs/Anims/SKULL_SPIN/frame_12.png new file mode 100644 index 0000000000..e2adba2bec Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/SKULL_SPIN/frame_12.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/SKULL_SPIN/frame_13.png b/assets/dolphin/custom/WatchDogs/Anims/SKULL_SPIN/frame_13.png new file mode 100644 index 0000000000..5e8de9e3bd Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/SKULL_SPIN/frame_13.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/SKULL_SPIN/frame_14.png b/assets/dolphin/custom/WatchDogs/Anims/SKULL_SPIN/frame_14.png new file mode 100644 index 0000000000..76ca1d5205 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/SKULL_SPIN/frame_14.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/SKULL_SPIN/frame_15.png b/assets/dolphin/custom/WatchDogs/Anims/SKULL_SPIN/frame_15.png new file mode 100644 index 0000000000..e215498e1c Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/SKULL_SPIN/frame_15.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/SKULL_SPIN/frame_16.png b/assets/dolphin/custom/WatchDogs/Anims/SKULL_SPIN/frame_16.png new file mode 100644 index 0000000000..0971331c9a Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/SKULL_SPIN/frame_16.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/SKULL_SPIN/frame_17.png b/assets/dolphin/custom/WatchDogs/Anims/SKULL_SPIN/frame_17.png new file mode 100644 index 0000000000..1dfacb0b1d Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/SKULL_SPIN/frame_17.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/SKULL_SPIN/frame_18.png b/assets/dolphin/custom/WatchDogs/Anims/SKULL_SPIN/frame_18.png new file mode 100644 index 0000000000..03a9d8992c Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/SKULL_SPIN/frame_18.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/SKULL_SPIN/frame_2.png b/assets/dolphin/custom/WatchDogs/Anims/SKULL_SPIN/frame_2.png new file mode 100644 index 0000000000..f45528f3e1 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/SKULL_SPIN/frame_2.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/SKULL_SPIN/frame_3.png b/assets/dolphin/custom/WatchDogs/Anims/SKULL_SPIN/frame_3.png new file mode 100644 index 0000000000..c03ca4ed69 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/SKULL_SPIN/frame_3.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/SKULL_SPIN/frame_4.png b/assets/dolphin/custom/WatchDogs/Anims/SKULL_SPIN/frame_4.png new file mode 100644 index 0000000000..83458fdeb4 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/SKULL_SPIN/frame_4.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/SKULL_SPIN/frame_5.png b/assets/dolphin/custom/WatchDogs/Anims/SKULL_SPIN/frame_5.png new file mode 100644 index 0000000000..3ab218c476 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/SKULL_SPIN/frame_5.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/SKULL_SPIN/frame_6.png b/assets/dolphin/custom/WatchDogs/Anims/SKULL_SPIN/frame_6.png new file mode 100644 index 0000000000..5c9d22b818 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/SKULL_SPIN/frame_6.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/SKULL_SPIN/frame_7.png b/assets/dolphin/custom/WatchDogs/Anims/SKULL_SPIN/frame_7.png new file mode 100644 index 0000000000..45bc0c49cf Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/SKULL_SPIN/frame_7.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/SKULL_SPIN/frame_8.png b/assets/dolphin/custom/WatchDogs/Anims/SKULL_SPIN/frame_8.png new file mode 100644 index 0000000000..a172a92927 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/SKULL_SPIN/frame_8.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/SKULL_SPIN/frame_9.png b/assets/dolphin/custom/WatchDogs/Anims/SKULL_SPIN/frame_9.png new file mode 100644 index 0000000000..b9e1604203 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/SKULL_SPIN/frame_9.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/SKULL_SPIN/meta.txt b/assets/dolphin/custom/WatchDogs/Anims/SKULL_SPIN/meta.txt new file mode 100644 index 0000000000..53f5a9ef34 --- /dev/null +++ b/assets/dolphin/custom/WatchDogs/Anims/SKULL_SPIN/meta.txt @@ -0,0 +1,14 @@ +Filetype: Flipper Animation +Version: 1 + +Width: 128 +Height: 64 +Passive frames: 19 +Active frames: 0 +Frames order: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 +Active cycles: 0 +Frame rate: 4 +Duration: 3600 +Active cooldown: 0 + +Bubble slots: 0 diff --git a/assets/dolphin/custom/WatchDogs/Anims/SPIRAL/frame_0.png b/assets/dolphin/custom/WatchDogs/Anims/SPIRAL/frame_0.png new file mode 100644 index 0000000000..c06c86826f Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/SPIRAL/frame_0.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/SPIRAL/frame_1.png b/assets/dolphin/custom/WatchDogs/Anims/SPIRAL/frame_1.png new file mode 100644 index 0000000000..4310dabbc7 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/SPIRAL/frame_1.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/SPIRAL/frame_10.png b/assets/dolphin/custom/WatchDogs/Anims/SPIRAL/frame_10.png new file mode 100644 index 0000000000..abc935db1e Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/SPIRAL/frame_10.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/SPIRAL/frame_11.png b/assets/dolphin/custom/WatchDogs/Anims/SPIRAL/frame_11.png new file mode 100644 index 0000000000..6a868594f0 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/SPIRAL/frame_11.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/SPIRAL/frame_12.png b/assets/dolphin/custom/WatchDogs/Anims/SPIRAL/frame_12.png new file mode 100644 index 0000000000..df2e2b6755 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/SPIRAL/frame_12.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/SPIRAL/frame_13.png b/assets/dolphin/custom/WatchDogs/Anims/SPIRAL/frame_13.png new file mode 100644 index 0000000000..169f590ec0 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/SPIRAL/frame_13.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/SPIRAL/frame_14.png b/assets/dolphin/custom/WatchDogs/Anims/SPIRAL/frame_14.png new file mode 100644 index 0000000000..d1967edb61 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/SPIRAL/frame_14.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/SPIRAL/frame_15.png b/assets/dolphin/custom/WatchDogs/Anims/SPIRAL/frame_15.png new file mode 100644 index 0000000000..41c8ef76bd Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/SPIRAL/frame_15.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/SPIRAL/frame_16.png b/assets/dolphin/custom/WatchDogs/Anims/SPIRAL/frame_16.png new file mode 100644 index 0000000000..1a749804b9 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/SPIRAL/frame_16.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/SPIRAL/frame_17.png b/assets/dolphin/custom/WatchDogs/Anims/SPIRAL/frame_17.png new file mode 100644 index 0000000000..53b713bb63 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/SPIRAL/frame_17.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/SPIRAL/frame_18.png b/assets/dolphin/custom/WatchDogs/Anims/SPIRAL/frame_18.png new file mode 100644 index 0000000000..57e6ce75b8 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/SPIRAL/frame_18.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/SPIRAL/frame_19.png b/assets/dolphin/custom/WatchDogs/Anims/SPIRAL/frame_19.png new file mode 100644 index 0000000000..e65d8b0fae Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/SPIRAL/frame_19.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/SPIRAL/frame_2.png b/assets/dolphin/custom/WatchDogs/Anims/SPIRAL/frame_2.png new file mode 100644 index 0000000000..1a4fc630b4 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/SPIRAL/frame_2.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/SPIRAL/frame_20.png b/assets/dolphin/custom/WatchDogs/Anims/SPIRAL/frame_20.png new file mode 100644 index 0000000000..a8c05339a6 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/SPIRAL/frame_20.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/SPIRAL/frame_21.png b/assets/dolphin/custom/WatchDogs/Anims/SPIRAL/frame_21.png new file mode 100644 index 0000000000..620f48cee9 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/SPIRAL/frame_21.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/SPIRAL/frame_22.png b/assets/dolphin/custom/WatchDogs/Anims/SPIRAL/frame_22.png new file mode 100644 index 0000000000..2074676c2f Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/SPIRAL/frame_22.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/SPIRAL/frame_23.png b/assets/dolphin/custom/WatchDogs/Anims/SPIRAL/frame_23.png new file mode 100644 index 0000000000..85ebcc35de Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/SPIRAL/frame_23.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/SPIRAL/frame_3.png b/assets/dolphin/custom/WatchDogs/Anims/SPIRAL/frame_3.png new file mode 100644 index 0000000000..0ebb5c7bee Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/SPIRAL/frame_3.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/SPIRAL/frame_4.png b/assets/dolphin/custom/WatchDogs/Anims/SPIRAL/frame_4.png new file mode 100644 index 0000000000..2e0f8cec68 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/SPIRAL/frame_4.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/SPIRAL/frame_5.png b/assets/dolphin/custom/WatchDogs/Anims/SPIRAL/frame_5.png new file mode 100644 index 0000000000..6b5bb888a4 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/SPIRAL/frame_5.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/SPIRAL/frame_6.png b/assets/dolphin/custom/WatchDogs/Anims/SPIRAL/frame_6.png new file mode 100644 index 0000000000..d3f3ed448d Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/SPIRAL/frame_6.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/SPIRAL/frame_7.png b/assets/dolphin/custom/WatchDogs/Anims/SPIRAL/frame_7.png new file mode 100644 index 0000000000..f4d15610df Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/SPIRAL/frame_7.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/SPIRAL/frame_8.png b/assets/dolphin/custom/WatchDogs/Anims/SPIRAL/frame_8.png new file mode 100644 index 0000000000..cb69658017 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/SPIRAL/frame_8.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/SPIRAL/frame_9.png b/assets/dolphin/custom/WatchDogs/Anims/SPIRAL/frame_9.png new file mode 100644 index 0000000000..9415c239dd Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Anims/SPIRAL/frame_9.png differ diff --git a/assets/dolphin/custom/WatchDogs/Anims/SPIRAL/meta.txt b/assets/dolphin/custom/WatchDogs/Anims/SPIRAL/meta.txt new file mode 100644 index 0000000000..81cc6c7d92 --- /dev/null +++ b/assets/dolphin/custom/WatchDogs/Anims/SPIRAL/meta.txt @@ -0,0 +1,14 @@ +Filetype: Flipper Animation +Version: 1 + +Width: 128 +Height: 64 +Passive frames: 24 +Active frames: 0 +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 +Active cycles: 0 +Frame rate: 4 +Duration: 3600 +Active cooldown: 0 + +Bubble slots: 0 diff --git a/assets/dolphin/custom/WatchDogs/Anims/manifest.txt b/assets/dolphin/custom/WatchDogs/Anims/manifest.txt new file mode 100644 index 0000000000..5e82ab29c5 --- /dev/null +++ b/assets/dolphin/custom/WatchDogs/Anims/manifest.txt @@ -0,0 +1,142 @@ +Filetype: Flipper Animation Manifest +Version: 1 + +Name: BOTTY_CALL +Min butthurt: 0 +Max butthurt: 18 +Min level: 1 +Max level: 30 +Weight: 3 + +Name: DEDSEC_AD +Min butthurt: 0 +Max butthurt: 18 +Min level: 1 +Max level: 30 +Weight: 3 + +Name: DEDSEC_ANIM +Min butthurt: 0 +Max butthurt: 18 +Min level: 1 +Max level: 30 +Weight: 3 + +Name: DEDSEC_ASCII +Min butthurt: 0 +Max butthurt: 18 +Min level: 1 +Max level: 30 +Weight: 3 + +Name: DEDSEC_LOGO +Min butthurt: 0 +Max butthurt: 18 +Min level: 1 +Max level: 30 +Weight: 3 + +Name: DEDSEC_OLD +Min butthurt: 0 +Max butthurt: 18 +Min level: 1 +Max level: 30 +Weight: 3 + +Name: DEDSEC_TALK +Min butthurt: 0 +Max butthurt: 18 +Min level: 1 +Max level: 30 +Weight: 3 + +Name: DEDSEC_WAVE +Min butthurt: 0 +Max butthurt: 18 +Min level: 1 +Max level: 30 +Weight: 3 + +Name: FINGER +Min butthurt: 0 +Max butthurt: 18 +Min level: 1 +Max level: 30 +Weight: 3 + +Name: GUNS_CAR +Min butthurt: 0 +Max butthurt: 18 +Min level: 1 +Max level: 30 +Weight: 3 + +Name: HANDS +Min butthurt: 0 +Max butthurt: 18 +Min level: 1 +Max level: 30 +Weight: 3 + +Name: JOIN_US +Min butthurt: 0 +Max butthurt: 18 +Min level: 1 +Max level: 30 +Weight: 3 + +Name: LOGO_WD2 +Min butthurt: 0 +Max butthurt: 18 +Min level: 1 +Max level: 30 +Weight: 3 + +Name: MARCUS +Min butthurt: 0 +Max butthurt: 18 +Min level: 1 +Max level: 30 +Weight: 3 + +Name: MUMMY +Min butthurt: 0 +Max butthurt: 18 +Min level: 1 +Max level: 30 +Weight: 3 + +Name: REAPER +Min butthurt: 0 +Max butthurt: 18 +Min level: 1 +Max level: 30 +Weight: 3 + +Name: REAPER_ALT +Min butthurt: 0 +Max butthurt: 18 +Min level: 1 +Max level: 30 +Weight: 3 + +Name: SKULL +Min butthurt: 0 +Max butthurt: 18 +Min level: 1 +Max level: 30 +Weight: 3 + +Name: SKULL_SPIN +Min butthurt: 0 +Max butthurt: 18 +Min level: 1 +Max level: 30 +Weight: 3 + +Name: SPIRAL +Min butthurt: 0 +Max butthurt: 18 +Min level: 1 +Max level: 30 +Weight: 3 diff --git a/assets/dolphin/custom/WatchDogs/Icons/NFC/NFC_dolphin_emulation_47x61.png b/assets/dolphin/custom/WatchDogs/Icons/NFC/NFC_dolphin_emulation_47x61.png new file mode 100644 index 0000000000..7df750e849 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Icons/NFC/NFC_dolphin_emulation_47x61.png differ diff --git a/assets/dolphin/custom/WatchDogs/Icons/Passport/passport_bad_46x49.png b/assets/dolphin/custom/WatchDogs/Icons/Passport/passport_bad_46x49.png new file mode 100644 index 0000000000..5d4348d3c7 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Icons/Passport/passport_bad_46x49.png differ diff --git a/assets/dolphin/custom/WatchDogs/Icons/Passport/passport_happy_46x49.png b/assets/dolphin/custom/WatchDogs/Icons/Passport/passport_happy_46x49.png new file mode 100644 index 0000000000..657c8c3520 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Icons/Passport/passport_happy_46x49.png differ diff --git a/assets/dolphin/custom/WatchDogs/Icons/Passport/passport_okay_46x49.png b/assets/dolphin/custom/WatchDogs/Icons/Passport/passport_okay_46x49.png new file mode 100644 index 0000000000..10383b31b7 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Icons/Passport/passport_okay_46x49.png differ diff --git a/assets/dolphin/custom/WatchDogs/Icons/RFID/RFIDDolphinReceive_97x61.png b/assets/dolphin/custom/WatchDogs/Icons/RFID/RFIDDolphinReceive_97x61.png new file mode 100644 index 0000000000..7e25d8e209 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Icons/RFID/RFIDDolphinReceive_97x61.png differ diff --git a/assets/dolphin/custom/WatchDogs/Icons/RFID/RFIDDolphinSend_97x61.png b/assets/dolphin/custom/WatchDogs/Icons/RFID/RFIDDolphinSend_97x61.png new file mode 100644 index 0000000000..0639f49966 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Icons/RFID/RFIDDolphinSend_97x61.png differ diff --git a/assets/dolphin/custom/WatchDogs/Icons/RFID/rfid_success.png b/assets/dolphin/custom/WatchDogs/Icons/RFID/rfid_success.png new file mode 100644 index 0000000000..8954004e00 Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Icons/RFID/rfid_success.png differ diff --git a/assets/dolphin/custom/WatchDogs/Icons/SubGhz/Scanning_123x52.png b/assets/dolphin/custom/WatchDogs/Icons/SubGhz/Scanning_123x52.png new file mode 100644 index 0000000000..fd6762e65b Binary files /dev/null and b/assets/dolphin/custom/WatchDogs/Icons/SubGhz/Scanning_123x52.png differ diff --git a/assets/dolphin/external/nsfw/manifest.txt b/assets/dolphin/external/nsfw/manifest.txt index c9cba41d46..4635b07445 100644 --- a/assets/dolphin/external/nsfw/manifest.txt +++ b/assets/dolphin/external/nsfw/manifest.txt @@ -1,219 +1,219 @@ Filetype: Flipper Animation Manifest Version: 1 -Name: nsfw/lvl_1 +Name: lvl_1 Min butthurt: 0 Max butthurt: 14 Min level: 1 Max level: 30 Weight: 7 -Name: nsfw/lvl_2 +Name: lvl_2 Min butthurt: 0 Max butthurt: 14 Min level: 2 Max level: 30 Weight: 7 -Name: nsfw/lvl_3 +Name: lvl_3 Min butthurt: 0 Max butthurt: 14 Min level: 3 Max level: 30 Weight: 7 -Name: nsfw/lvl_4 +Name: lvl_4 Min butthurt: 0 Max butthurt: 14 Min level: 4 Max level: 30 Weight: 7 -Name: nsfw/lvl_5 +Name: lvl_5 Min butthurt: 0 Max butthurt: 14 Min level: 5 Max level: 30 Weight: 7 -Name: nsfw/lvl_6 +Name: lvl_6 Min butthurt: 0 Max butthurt: 14 Min level: 6 Max level: 30 Weight: 7 -Name: nsfw/lvl_7 +Name: lvl_7 Min butthurt: 0 Max butthurt: 14 Min level: 7 Max level: 30 Weight: 7 -Name: nsfw/lvl_8 +Name: lvl_8 Min butthurt: 0 Max butthurt: 14 Min level: 8 Max level: 30 Weight: 7 -Name: nsfw/lvl_9 +Name: lvl_9 Min butthurt: 0 Max butthurt: 14 Min level: 9 Max level: 30 Weight: 7 -Name: nsfw/lvl_10 +Name: lvl_10 Min butthurt: 0 Max butthurt: 14 Min level: 10 Max level: 30 Weight: 7 -Name: nsfw/lvl_11 +Name: lvl_11 Min butthurt: 0 Max butthurt: 14 Min level: 11 Max level: 30 Weight: 9 -Name: nsfw/PaxGod_TikTok_Marketing +Name: PaxGod_TikTok_Marketing Min butthurt: 0 Max butthurt: 14 Min level: 11 Max level: 30 Weight: 3 -Name: nsfw/lvl_12 +Name: lvl_12 Min butthurt: 0 Max butthurt: 14 Min level: 12 Max level: 30 Weight: 7 -Name: nsfw/lvl_13 +Name: lvl_13 Min butthurt: 0 Max butthurt: 14 Min level: 13 Max level: 30 Weight: 7 -Name: nsfw/lvl_14 +Name: lvl_14 Min butthurt: 0 Max butthurt: 14 Min level: 14 Max level: 30 Weight: 7 -Name: nsfw/lvl_15 +Name: lvl_15 Min butthurt: 0 Max butthurt: 14 Min level: 15 Max level: 30 Weight: 7 -Name: nsfw/lvl_16 +Name: lvl_16 Min butthurt: 0 Max butthurt: 14 Min level: 16 Max level: 30 Weight: 7 -Name: nsfw/lvl_17 +Name: lvl_17 Min butthurt: 0 Max butthurt: 14 Min level: 17 Max level: 30 Weight: 7 -Name: nsfw/lvl_18 +Name: lvl_18 Min butthurt: 0 Max butthurt: 14 Min level: 18 Max level: 30 Weight: 7 -Name: nsfw/lvl_19 +Name: lvl_19 Min butthurt: 0 Max butthurt: 14 Min level: 19 Max level: 30 Weight: 7 -Name: nsfw/lvl_20 +Name: lvl_20 Min butthurt: 0 Max butthurt: 14 Min level: 20 Max level: 30 Weight: 7 -Name: nsfw/lvl_21 +Name: lvl_21 Min butthurt: 0 Max butthurt: 14 Min level: 21 Max level: 30 Weight: 9 -Name: nsfw/lvl_22 +Name: lvl_22 Min butthurt: 0 Max butthurt: 14 Min level: 22 Max level: 30 Weight: 7 -Name: nsfw/lvl_23 +Name: lvl_23 Min butthurt: 0 Max butthurt: 14 Min level: 23 Max level: 30 Weight: 7 -Name: nsfw/lvl_24 +Name: lvl_24 Min butthurt: 0 Max butthurt: 14 Min level: 24 Max level: 30 Weight: 7 -Name: nsfw/lvl_25 +Name: lvl_25 Min butthurt: 0 Max butthurt: 14 Min level: 25 Max level: 30 Weight: 7 -Name: nsfw/lvl_26 +Name: lvl_26 Min butthurt: 0 Max butthurt: 14 Min level: 26 Max level: 30 Weight: 7 -Name: nsfw/lvl_27 +Name: lvl_27 Min butthurt: 0 Max butthurt: 14 Min level: 27 Max level: 30 Weight: 7 -Name: nsfw/lvl_28 +Name: lvl_28 Min butthurt: 0 Max butthurt: 14 Min level: 28 Max level: 30 Weight: 7 -Name: nsfw/lvl_29 +Name: lvl_29 Min butthurt: 0 Max butthurt: 14 Min level: 29 Max level: 30 Weight: 7 -Name: nsfw/lvl_30 +Name: lvl_30 Min butthurt: 0 Max butthurt: 14 Min level: 30 Max level: 30 -Weight: 9 \ No newline at end of file +Weight: 9 diff --git a/assets/dolphin/external/nsfw/no_lvl_up_manifest.txt b/assets/dolphin/external/nsfw/no_lvl_up_manifest.txt deleted file mode 100644 index 2027b1c9f0..0000000000 --- a/assets/dolphin/external/nsfw/no_lvl_up_manifest.txt +++ /dev/null @@ -1,219 +0,0 @@ -Filetype: Flipper Animation Manifest -Version: 1 - -Name: nsfw/lvl_1 -Min butthurt: 0 -Max butthurt: 14 -Min level: 1 -Max level: 30 -Weight: 7 - -Name: nsfw/lvl_2 -Min butthurt: 0 -Max butthurt: 14 -Min level: 1 -Max level: 30 -Weight: 7 - -Name: nsfw/lvl_3 -Min butthurt: 0 -Max butthurt: 14 -Min level: 1 -Max level: 30 -Weight: 7 - -Name: nsfw/lvl_4 -Min butthurt: 0 -Max butthurt: 14 -Min level: 1 -Max level: 30 -Weight: 7 - -Name: nsfw/lvl_5 -Min butthurt: 0 -Max butthurt: 14 -Min level: 1 -Max level: 30 -Weight: 7 - -Name: nsfw/lvl_6 -Min butthurt: 0 -Max butthurt: 14 -Min level: 1 -Max level: 30 -Weight: 7 - -Name: nsfw/lvl_7 -Min butthurt: 0 -Max butthurt: 14 -Min level: 1 -Max level: 30 -Weight: 7 - -Name: nsfw/lvl_8 -Min butthurt: 0 -Max butthurt: 14 -Min level: 1 -Max level: 30 -Weight: 7 - -Name: nsfw/lvl_9 -Min butthurt: 0 -Max butthurt: 14 -Min level: 1 -Max level: 30 -Weight: 7 - -Name: nsfw/lvl_10 -Min butthurt: 0 -Max butthurt: 14 -Min level: 1 -Max level: 30 -Weight: 7 - -Name: nsfw/lvl_11 -Min butthurt: 0 -Max butthurt: 14 -Min level: 1 -Max level: 30 -Weight: 9 - -Name: nsfw/PaxGod_TikTok_Marketing -Min butthurt: 0 -Max butthurt: 14 -Min level: 1 -Max level: 30 -Weight: 3 - -Name: nsfw/lvl_12 -Min butthurt: 0 -Max butthurt: 14 -Min level: 1 -Max level: 30 -Weight: 7 - -Name: nsfw/lvl_13 -Min butthurt: 0 -Max butthurt: 14 -Min level: 1 -Max level: 30 -Weight: 7 - -Name: nsfw/lvl_14 -Min butthurt: 0 -Max butthurt: 14 -Min level: 1 -Max level: 30 -Weight: 7 - -Name: nsfw/lvl_15 -Min butthurt: 0 -Max butthurt: 14 -Min level: 1 -Max level: 30 -Weight: 7 - -Name: nsfw/lvl_16 -Min butthurt: 0 -Max butthurt: 14 -Min level: 1 -Max level: 30 -Weight: 7 - -Name: nsfw/lvl_17 -Min butthurt: 0 -Max butthurt: 14 -Min level: 1 -Max level: 30 -Weight: 7 - -Name: nsfw/lvl_18 -Min butthurt: 0 -Max butthurt: 14 -Min level: 1 -Max level: 30 -Weight: 7 - -Name: nsfw/lvl_19 -Min butthurt: 0 -Max butthurt: 14 -Min level: 1 -Max level: 30 -Weight: 7 - -Name: nsfw/lvl_20 -Min butthurt: 0 -Max butthurt: 14 -Min level: 1 -Max level: 30 -Weight: 7 - -Name: nsfw/lvl_21 -Min butthurt: 0 -Max butthurt: 14 -Min level: 1 -Max level: 30 -Weight: 9 - -Name: nsfw/lvl_22 -Min butthurt: 0 -Max butthurt: 14 -Min level: 1 -Max level: 30 -Weight: 7 - -Name: nsfw/lvl_23 -Min butthurt: 0 -Max butthurt: 14 -Min level: 1 -Max level: 30 -Weight: 7 - -Name: nsfw/lvl_24 -Min butthurt: 0 -Max butthurt: 14 -Min level: 1 -Max level: 30 -Weight: 7 - -Name: nsfw/lvl_25 -Min butthurt: 0 -Max butthurt: 14 -Min level: 1 -Max level: 30 -Weight: 7 - -Name: nsfw/lvl_26 -Min butthurt: 0 -Max butthurt: 14 -Min level: 1 -Max level: 30 -Weight: 7 - -Name: nsfw/lvl_27 -Min butthurt: 0 -Max butthurt: 14 -Min level: 1 -Max level: 30 -Weight: 7 - -Name: nsfw/lvl_28 -Min butthurt: 0 -Max butthurt: 14 -Min level: 1 -Max level: 30 -Weight: 7 - -Name: nsfw/lvl_29 -Min butthurt: 0 -Max butthurt: 14 -Min level: 1 -Max level: 30 -Weight: 7 - -Name: nsfw/lvl_30 -Min butthurt: 0 -Max butthurt: 14 -Min level: 1 -Max level: 30 -Weight: 9 \ No newline at end of file diff --git a/assets/dolphin/external/sfw/manifest.txt b/assets/dolphin/external/sfw/manifest.txt index 0702773500..fbc438c000 100644 --- a/assets/dolphin/external/sfw/manifest.txt +++ b/assets/dolphin/external/sfw/manifest.txt @@ -1,149 +1,149 @@ Filetype: Flipper Animation Manifest Version: 1 -Name: sfw/L1_Waves_128x50 +Name: L1_Waves_128x50 Min butthurt: 0 Max butthurt: 5 Min level: 1 Max level: 30 Weight: 3 -Name: sfw/L1_Laptop_128x51 +Name: L1_Laptop_128x51 Min butthurt: 0 Max butthurt: 7 -Min level: 1 +Min level: 2 Max level: 30 Weight: 3 -Name: sfw/L1_Sleep_128x64 +Name: L1_Sleigh_ride_128x64 Min butthurt: 0 -Max butthurt: 10 -Min level: 1 +Max butthurt: 14 +Min level: 4 Max level: 30 -Weight: 3 +Weight: 4 -Name: sfw/L1_Recording_128x51 +Name: L1_Sleep_128x64 Min butthurt: 0 -Max butthurt: 8 -Min level: 1 +Max butthurt: 10 +Min level: 5 Max level: 30 Weight: 3 -Name: sfw/L1_Furippa1_128x64 +Name: L1_Recording_128x51 Min butthurt: 0 -Max butthurt: 6 -Min level: 1 +Max butthurt: 8 +Min level: 7 Max level: 30 Weight: 3 -Name: sfw/L1_Happy_holidays_128x64 +Name: L1_Happy_holidays_128x64 Min butthurt: 0 Max butthurt: 14 -Min level: 1 +Min level: 8 Max level: 30 Weight: 4 -Name: sfw/L1_Read_books_128x64 +Name: L1_Furippa1_128x64 +Min butthurt: 0 +Max butthurt: 6 +Min level: 10 +Max level: 30 +Weight: 3 + +Name: L1_Read_books_128x64 Min butthurt: 0 Max butthurt: 8 -Min level: 1 +Min level: 11 Max level: 30 Weight: 3 -Name: sfw/L1_Cry_128x64 +Name: L1_Cry_128x64 Min butthurt: 8 Max butthurt: 13 -Min level: 1 +Min level: 12 Max level: 30 Weight: 3 -Name: sfw/L1_Boxing_128x64 +Name: L1_Boxing_128x64 Min butthurt: 10 Max butthurt: 13 -Min level: 1 +Min level: 14 Max level: 30 Weight: 3 -Name: sfw/L1_Mad_fist_128x64 +Name: L1_Mad_fist_128x64 Min butthurt: 9 Max butthurt: 13 -Min level: 1 +Min level: 15 Max level: 30 Weight: 3 -Name: sfw/L1_Mods_128x64 +Name: L1_Mods_128x64 Min butthurt: 0 Max butthurt: 9 -Min level: 1 +Min level: 17 Max level: 30 Weight: 4 -Name: sfw/L1_Painting_128x64 +Name: L1_Painting_128x64 Min butthurt: 0 Max butthurt: 7 -Min level: 1 +Min level: 18 Max level: 30 Weight: 3 -Name: sfw/L1_Leaving_sad_128x64 +Name: L2_Furippa2_128x64 +Min butthurt: 0 +Max butthurt: 6 +Min level: 20 +Max level: 30 +Weight: 3 + +Name: L1_Leaving_sad_128x64 Min butthurt: 14 Max butthurt: 14 -Min level: 1 +Min level: 21 Max level: 30 Weight: 3 -Name: sfw/L2_Wake_up_128x64 +Name: L2_Wake_up_128x64 Min butthurt: 0 Max butthurt: 12 -Min level: 1 +Min level: 22 Max level: 30 Weight: 4 -Name: sfw/L2_Furippa2_128x64 -Min butthurt: 0 -Max butthurt: 6 -Min level: 1 -Max level: 30 -Weight: 3 - -Name: sfw/L2_Hacking_pc_128x64 +Name: L2_Hacking_pc_128x64 Min butthurt: 0 Max butthurt: 8 -Min level: 1 +Min level: 24 Max level: 30 Weight: 3 -Name: sfw/L2_Soldering_128x64 +Name: L2_Soldering_128x64 Min butthurt: 0 Max butthurt: 10 -Min level: 1 +Min level: 25 Max level: 30 Weight: 3 -Name: sfw/L3_Furippa3_128x64 +Name: L3_Lab_research_128x54 Min butthurt: 0 -Max butthurt: 6 -Min level: 1 +Max butthurt: 10 +Min level: 27 Max level: 30 Weight: 3 -Name: sfw/L3_Hijack_radio_128x64 +Name: L3_Hijack_radio_128x64 Min butthurt: 0 Max butthurt: 8 -Min level: 1 +Min level: 28 Max level: 30 Weight: 3 -Name: sfw/L3_Lab_research_128x54 +Name: L3_Furippa3_128x64 Min butthurt: 0 -Max butthurt: 10 -Min level: 1 +Max butthurt: 6 +Min level: 30 Max level: 30 Weight: 3 - -Name: sfw/L1_Sleigh_ride_128x64 -Min butthurt: 0 -Max butthurt: 14 -Min level: 1 -Max level: 30 -Weight: 4 \ No newline at end of file diff --git a/assets/resources/dolphin/nsfw/manifest.txt b/assets/resources/dolphin/nsfw/manifest.txt index c9cba41d46..4635b07445 100644 --- a/assets/resources/dolphin/nsfw/manifest.txt +++ b/assets/resources/dolphin/nsfw/manifest.txt @@ -1,219 +1,219 @@ Filetype: Flipper Animation Manifest Version: 1 -Name: nsfw/lvl_1 +Name: lvl_1 Min butthurt: 0 Max butthurt: 14 Min level: 1 Max level: 30 Weight: 7 -Name: nsfw/lvl_2 +Name: lvl_2 Min butthurt: 0 Max butthurt: 14 Min level: 2 Max level: 30 Weight: 7 -Name: nsfw/lvl_3 +Name: lvl_3 Min butthurt: 0 Max butthurt: 14 Min level: 3 Max level: 30 Weight: 7 -Name: nsfw/lvl_4 +Name: lvl_4 Min butthurt: 0 Max butthurt: 14 Min level: 4 Max level: 30 Weight: 7 -Name: nsfw/lvl_5 +Name: lvl_5 Min butthurt: 0 Max butthurt: 14 Min level: 5 Max level: 30 Weight: 7 -Name: nsfw/lvl_6 +Name: lvl_6 Min butthurt: 0 Max butthurt: 14 Min level: 6 Max level: 30 Weight: 7 -Name: nsfw/lvl_7 +Name: lvl_7 Min butthurt: 0 Max butthurt: 14 Min level: 7 Max level: 30 Weight: 7 -Name: nsfw/lvl_8 +Name: lvl_8 Min butthurt: 0 Max butthurt: 14 Min level: 8 Max level: 30 Weight: 7 -Name: nsfw/lvl_9 +Name: lvl_9 Min butthurt: 0 Max butthurt: 14 Min level: 9 Max level: 30 Weight: 7 -Name: nsfw/lvl_10 +Name: lvl_10 Min butthurt: 0 Max butthurt: 14 Min level: 10 Max level: 30 Weight: 7 -Name: nsfw/lvl_11 +Name: lvl_11 Min butthurt: 0 Max butthurt: 14 Min level: 11 Max level: 30 Weight: 9 -Name: nsfw/PaxGod_TikTok_Marketing +Name: PaxGod_TikTok_Marketing Min butthurt: 0 Max butthurt: 14 Min level: 11 Max level: 30 Weight: 3 -Name: nsfw/lvl_12 +Name: lvl_12 Min butthurt: 0 Max butthurt: 14 Min level: 12 Max level: 30 Weight: 7 -Name: nsfw/lvl_13 +Name: lvl_13 Min butthurt: 0 Max butthurt: 14 Min level: 13 Max level: 30 Weight: 7 -Name: nsfw/lvl_14 +Name: lvl_14 Min butthurt: 0 Max butthurt: 14 Min level: 14 Max level: 30 Weight: 7 -Name: nsfw/lvl_15 +Name: lvl_15 Min butthurt: 0 Max butthurt: 14 Min level: 15 Max level: 30 Weight: 7 -Name: nsfw/lvl_16 +Name: lvl_16 Min butthurt: 0 Max butthurt: 14 Min level: 16 Max level: 30 Weight: 7 -Name: nsfw/lvl_17 +Name: lvl_17 Min butthurt: 0 Max butthurt: 14 Min level: 17 Max level: 30 Weight: 7 -Name: nsfw/lvl_18 +Name: lvl_18 Min butthurt: 0 Max butthurt: 14 Min level: 18 Max level: 30 Weight: 7 -Name: nsfw/lvl_19 +Name: lvl_19 Min butthurt: 0 Max butthurt: 14 Min level: 19 Max level: 30 Weight: 7 -Name: nsfw/lvl_20 +Name: lvl_20 Min butthurt: 0 Max butthurt: 14 Min level: 20 Max level: 30 Weight: 7 -Name: nsfw/lvl_21 +Name: lvl_21 Min butthurt: 0 Max butthurt: 14 Min level: 21 Max level: 30 Weight: 9 -Name: nsfw/lvl_22 +Name: lvl_22 Min butthurt: 0 Max butthurt: 14 Min level: 22 Max level: 30 Weight: 7 -Name: nsfw/lvl_23 +Name: lvl_23 Min butthurt: 0 Max butthurt: 14 Min level: 23 Max level: 30 Weight: 7 -Name: nsfw/lvl_24 +Name: lvl_24 Min butthurt: 0 Max butthurt: 14 Min level: 24 Max level: 30 Weight: 7 -Name: nsfw/lvl_25 +Name: lvl_25 Min butthurt: 0 Max butthurt: 14 Min level: 25 Max level: 30 Weight: 7 -Name: nsfw/lvl_26 +Name: lvl_26 Min butthurt: 0 Max butthurt: 14 Min level: 26 Max level: 30 Weight: 7 -Name: nsfw/lvl_27 +Name: lvl_27 Min butthurt: 0 Max butthurt: 14 Min level: 27 Max level: 30 Weight: 7 -Name: nsfw/lvl_28 +Name: lvl_28 Min butthurt: 0 Max butthurt: 14 Min level: 28 Max level: 30 Weight: 7 -Name: nsfw/lvl_29 +Name: lvl_29 Min butthurt: 0 Max butthurt: 14 Min level: 29 Max level: 30 Weight: 7 -Name: nsfw/lvl_30 +Name: lvl_30 Min butthurt: 0 Max butthurt: 14 Min level: 30 Max level: 30 -Weight: 9 \ No newline at end of file +Weight: 9 diff --git a/assets/resources/dolphin/nsfw/no_lvl_up_manifest.txt b/assets/resources/dolphin/nsfw/no_lvl_up_manifest.txt deleted file mode 100644 index 2027b1c9f0..0000000000 --- a/assets/resources/dolphin/nsfw/no_lvl_up_manifest.txt +++ /dev/null @@ -1,219 +0,0 @@ -Filetype: Flipper Animation Manifest -Version: 1 - -Name: nsfw/lvl_1 -Min butthurt: 0 -Max butthurt: 14 -Min level: 1 -Max level: 30 -Weight: 7 - -Name: nsfw/lvl_2 -Min butthurt: 0 -Max butthurt: 14 -Min level: 1 -Max level: 30 -Weight: 7 - -Name: nsfw/lvl_3 -Min butthurt: 0 -Max butthurt: 14 -Min level: 1 -Max level: 30 -Weight: 7 - -Name: nsfw/lvl_4 -Min butthurt: 0 -Max butthurt: 14 -Min level: 1 -Max level: 30 -Weight: 7 - -Name: nsfw/lvl_5 -Min butthurt: 0 -Max butthurt: 14 -Min level: 1 -Max level: 30 -Weight: 7 - -Name: nsfw/lvl_6 -Min butthurt: 0 -Max butthurt: 14 -Min level: 1 -Max level: 30 -Weight: 7 - -Name: nsfw/lvl_7 -Min butthurt: 0 -Max butthurt: 14 -Min level: 1 -Max level: 30 -Weight: 7 - -Name: nsfw/lvl_8 -Min butthurt: 0 -Max butthurt: 14 -Min level: 1 -Max level: 30 -Weight: 7 - -Name: nsfw/lvl_9 -Min butthurt: 0 -Max butthurt: 14 -Min level: 1 -Max level: 30 -Weight: 7 - -Name: nsfw/lvl_10 -Min butthurt: 0 -Max butthurt: 14 -Min level: 1 -Max level: 30 -Weight: 7 - -Name: nsfw/lvl_11 -Min butthurt: 0 -Max butthurt: 14 -Min level: 1 -Max level: 30 -Weight: 9 - -Name: nsfw/PaxGod_TikTok_Marketing -Min butthurt: 0 -Max butthurt: 14 -Min level: 1 -Max level: 30 -Weight: 3 - -Name: nsfw/lvl_12 -Min butthurt: 0 -Max butthurt: 14 -Min level: 1 -Max level: 30 -Weight: 7 - -Name: nsfw/lvl_13 -Min butthurt: 0 -Max butthurt: 14 -Min level: 1 -Max level: 30 -Weight: 7 - -Name: nsfw/lvl_14 -Min butthurt: 0 -Max butthurt: 14 -Min level: 1 -Max level: 30 -Weight: 7 - -Name: nsfw/lvl_15 -Min butthurt: 0 -Max butthurt: 14 -Min level: 1 -Max level: 30 -Weight: 7 - -Name: nsfw/lvl_16 -Min butthurt: 0 -Max butthurt: 14 -Min level: 1 -Max level: 30 -Weight: 7 - -Name: nsfw/lvl_17 -Min butthurt: 0 -Max butthurt: 14 -Min level: 1 -Max level: 30 -Weight: 7 - -Name: nsfw/lvl_18 -Min butthurt: 0 -Max butthurt: 14 -Min level: 1 -Max level: 30 -Weight: 7 - -Name: nsfw/lvl_19 -Min butthurt: 0 -Max butthurt: 14 -Min level: 1 -Max level: 30 -Weight: 7 - -Name: nsfw/lvl_20 -Min butthurt: 0 -Max butthurt: 14 -Min level: 1 -Max level: 30 -Weight: 7 - -Name: nsfw/lvl_21 -Min butthurt: 0 -Max butthurt: 14 -Min level: 1 -Max level: 30 -Weight: 9 - -Name: nsfw/lvl_22 -Min butthurt: 0 -Max butthurt: 14 -Min level: 1 -Max level: 30 -Weight: 7 - -Name: nsfw/lvl_23 -Min butthurt: 0 -Max butthurt: 14 -Min level: 1 -Max level: 30 -Weight: 7 - -Name: nsfw/lvl_24 -Min butthurt: 0 -Max butthurt: 14 -Min level: 1 -Max level: 30 -Weight: 7 - -Name: nsfw/lvl_25 -Min butthurt: 0 -Max butthurt: 14 -Min level: 1 -Max level: 30 -Weight: 7 - -Name: nsfw/lvl_26 -Min butthurt: 0 -Max butthurt: 14 -Min level: 1 -Max level: 30 -Weight: 7 - -Name: nsfw/lvl_27 -Min butthurt: 0 -Max butthurt: 14 -Min level: 1 -Max level: 30 -Weight: 7 - -Name: nsfw/lvl_28 -Min butthurt: 0 -Max butthurt: 14 -Min level: 1 -Max level: 30 -Weight: 7 - -Name: nsfw/lvl_29 -Min butthurt: 0 -Max butthurt: 14 -Min level: 1 -Max level: 30 -Weight: 7 - -Name: nsfw/lvl_30 -Min butthurt: 0 -Max butthurt: 14 -Min level: 1 -Max level: 30 -Weight: 9 \ No newline at end of file diff --git a/assets/resources/dolphin/sfw/manifest.txt b/assets/resources/dolphin/sfw/manifest.txt index 0702773500..fbc438c000 100644 --- a/assets/resources/dolphin/sfw/manifest.txt +++ b/assets/resources/dolphin/sfw/manifest.txt @@ -1,149 +1,149 @@ Filetype: Flipper Animation Manifest Version: 1 -Name: sfw/L1_Waves_128x50 +Name: L1_Waves_128x50 Min butthurt: 0 Max butthurt: 5 Min level: 1 Max level: 30 Weight: 3 -Name: sfw/L1_Laptop_128x51 +Name: L1_Laptop_128x51 Min butthurt: 0 Max butthurt: 7 -Min level: 1 +Min level: 2 Max level: 30 Weight: 3 -Name: sfw/L1_Sleep_128x64 +Name: L1_Sleigh_ride_128x64 Min butthurt: 0 -Max butthurt: 10 -Min level: 1 +Max butthurt: 14 +Min level: 4 Max level: 30 -Weight: 3 +Weight: 4 -Name: sfw/L1_Recording_128x51 +Name: L1_Sleep_128x64 Min butthurt: 0 -Max butthurt: 8 -Min level: 1 +Max butthurt: 10 +Min level: 5 Max level: 30 Weight: 3 -Name: sfw/L1_Furippa1_128x64 +Name: L1_Recording_128x51 Min butthurt: 0 -Max butthurt: 6 -Min level: 1 +Max butthurt: 8 +Min level: 7 Max level: 30 Weight: 3 -Name: sfw/L1_Happy_holidays_128x64 +Name: L1_Happy_holidays_128x64 Min butthurt: 0 Max butthurt: 14 -Min level: 1 +Min level: 8 Max level: 30 Weight: 4 -Name: sfw/L1_Read_books_128x64 +Name: L1_Furippa1_128x64 +Min butthurt: 0 +Max butthurt: 6 +Min level: 10 +Max level: 30 +Weight: 3 + +Name: L1_Read_books_128x64 Min butthurt: 0 Max butthurt: 8 -Min level: 1 +Min level: 11 Max level: 30 Weight: 3 -Name: sfw/L1_Cry_128x64 +Name: L1_Cry_128x64 Min butthurt: 8 Max butthurt: 13 -Min level: 1 +Min level: 12 Max level: 30 Weight: 3 -Name: sfw/L1_Boxing_128x64 +Name: L1_Boxing_128x64 Min butthurt: 10 Max butthurt: 13 -Min level: 1 +Min level: 14 Max level: 30 Weight: 3 -Name: sfw/L1_Mad_fist_128x64 +Name: L1_Mad_fist_128x64 Min butthurt: 9 Max butthurt: 13 -Min level: 1 +Min level: 15 Max level: 30 Weight: 3 -Name: sfw/L1_Mods_128x64 +Name: L1_Mods_128x64 Min butthurt: 0 Max butthurt: 9 -Min level: 1 +Min level: 17 Max level: 30 Weight: 4 -Name: sfw/L1_Painting_128x64 +Name: L1_Painting_128x64 Min butthurt: 0 Max butthurt: 7 -Min level: 1 +Min level: 18 Max level: 30 Weight: 3 -Name: sfw/L1_Leaving_sad_128x64 +Name: L2_Furippa2_128x64 +Min butthurt: 0 +Max butthurt: 6 +Min level: 20 +Max level: 30 +Weight: 3 + +Name: L1_Leaving_sad_128x64 Min butthurt: 14 Max butthurt: 14 -Min level: 1 +Min level: 21 Max level: 30 Weight: 3 -Name: sfw/L2_Wake_up_128x64 +Name: L2_Wake_up_128x64 Min butthurt: 0 Max butthurt: 12 -Min level: 1 +Min level: 22 Max level: 30 Weight: 4 -Name: sfw/L2_Furippa2_128x64 -Min butthurt: 0 -Max butthurt: 6 -Min level: 1 -Max level: 30 -Weight: 3 - -Name: sfw/L2_Hacking_pc_128x64 +Name: L2_Hacking_pc_128x64 Min butthurt: 0 Max butthurt: 8 -Min level: 1 +Min level: 24 Max level: 30 Weight: 3 -Name: sfw/L2_Soldering_128x64 +Name: L2_Soldering_128x64 Min butthurt: 0 Max butthurt: 10 -Min level: 1 +Min level: 25 Max level: 30 Weight: 3 -Name: sfw/L3_Furippa3_128x64 +Name: L3_Lab_research_128x54 Min butthurt: 0 -Max butthurt: 6 -Min level: 1 +Max butthurt: 10 +Min level: 27 Max level: 30 Weight: 3 -Name: sfw/L3_Hijack_radio_128x64 +Name: L3_Hijack_radio_128x64 Min butthurt: 0 Max butthurt: 8 -Min level: 1 +Min level: 28 Max level: 30 Weight: 3 -Name: sfw/L3_Lab_research_128x54 +Name: L3_Furippa3_128x64 Min butthurt: 0 -Max butthurt: 10 -Min level: 1 +Max butthurt: 6 +Min level: 30 Max level: 30 Weight: 3 - -Name: sfw/L1_Sleigh_ride_128x64 -Min butthurt: 0 -Max butthurt: 14 -Min level: 1 -Max level: 30 -Weight: 4 \ No newline at end of file diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/BOTTY_CALL/frame_0.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/BOTTY_CALL/frame_0.bm new file mode 100644 index 0000000000..4191af8b75 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/BOTTY_CALL/frame_0.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/BOTTY_CALL/frame_1.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/BOTTY_CALL/frame_1.bm new file mode 100644 index 0000000000..738c546f7b Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/BOTTY_CALL/frame_1.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/BOTTY_CALL/frame_2.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/BOTTY_CALL/frame_2.bm new file mode 100644 index 0000000000..432ab276e8 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/BOTTY_CALL/frame_2.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/BOTTY_CALL/meta.txt b/assets/resources/dolphin_custom/WatchDogs/Anims/BOTTY_CALL/meta.txt new file mode 100644 index 0000000000..0a08fc2a7e --- /dev/null +++ b/assets/resources/dolphin_custom/WatchDogs/Anims/BOTTY_CALL/meta.txt @@ -0,0 +1,14 @@ +Filetype: Flipper Animation +Version: 1 + +Width: 128 +Height: 64 +Passive frames: 3 +Active frames: 0 +Frames order: 0 1 2 +Active cycles: 0 +Frame rate: 2 +Duration: 3600 +Active cooldown: 0 + +Bubble slots: 0 diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_AD/frame_0.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_AD/frame_0.bm new file mode 100644 index 0000000000..aefb229419 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_AD/frame_0.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_AD/frame_1.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_AD/frame_1.bm new file mode 100644 index 0000000000..8efa98d5d4 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_AD/frame_1.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_AD/frame_10.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_AD/frame_10.bm new file mode 100644 index 0000000000..fdf9bbbcf7 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_AD/frame_10.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_AD/frame_11.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_AD/frame_11.bm new file mode 100644 index 0000000000..39771f0d4a Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_AD/frame_11.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_AD/frame_12.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_AD/frame_12.bm new file mode 100644 index 0000000000..39f9d33aec Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_AD/frame_12.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_AD/frame_13.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_AD/frame_13.bm new file mode 100644 index 0000000000..b4c0f5c265 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_AD/frame_13.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_AD/frame_14.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_AD/frame_14.bm new file mode 100644 index 0000000000..2f4af8aeb0 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_AD/frame_14.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_AD/frame_15.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_AD/frame_15.bm new file mode 100644 index 0000000000..4ff26b592e Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_AD/frame_15.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_AD/frame_16.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_AD/frame_16.bm new file mode 100644 index 0000000000..3890a7f1f3 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_AD/frame_16.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_AD/frame_2.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_AD/frame_2.bm new file mode 100644 index 0000000000..d230168947 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_AD/frame_2.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_AD/frame_3.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_AD/frame_3.bm new file mode 100644 index 0000000000..4063499346 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_AD/frame_3.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_AD/frame_4.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_AD/frame_4.bm new file mode 100644 index 0000000000..a4f88d02f8 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_AD/frame_4.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_AD/frame_5.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_AD/frame_5.bm new file mode 100644 index 0000000000..fcdbf766f0 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_AD/frame_5.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_AD/frame_6.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_AD/frame_6.bm new file mode 100644 index 0000000000..4926c87aa2 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_AD/frame_6.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_AD/frame_7.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_AD/frame_7.bm new file mode 100644 index 0000000000..dc42726f0a Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_AD/frame_7.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_AD/frame_8.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_AD/frame_8.bm new file mode 100644 index 0000000000..fcdbf766f0 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_AD/frame_8.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_AD/frame_9.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_AD/frame_9.bm new file mode 100644 index 0000000000..e69a019593 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_AD/frame_9.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_AD/meta.txt b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_AD/meta.txt new file mode 100644 index 0000000000..4991b01ee8 --- /dev/null +++ b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_AD/meta.txt @@ -0,0 +1,14 @@ +Filetype: Flipper Animation +Version: 1 + +Width: 128 +Height: 64 +Passive frames: 17 +Active frames: 0 +Frames order: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 +Active cycles: 0 +Frame rate: 4 +Duration: 3600 +Active cooldown: 0 + +Bubble slots: 0 diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_0.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_0.bm new file mode 100644 index 0000000000..4405801309 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_0.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_1.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_1.bm new file mode 100644 index 0000000000..5e7b0aea8d Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_1.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_10.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_10.bm new file mode 100644 index 0000000000..67457153ff Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_10.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_11.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_11.bm new file mode 100644 index 0000000000..b5a45a806b Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_11.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_12.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_12.bm new file mode 100644 index 0000000000..98bd18344b Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_12.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_13.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_13.bm new file mode 100644 index 0000000000..1e6bb9b1f5 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_13.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_14.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_14.bm new file mode 100644 index 0000000000..03fb3c0a31 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_14.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_15.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_15.bm new file mode 100644 index 0000000000..ad913dab7e Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_15.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_16.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_16.bm new file mode 100644 index 0000000000..edc706d8a0 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_16.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_17.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_17.bm new file mode 100644 index 0000000000..a6f6c2202b Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_17.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_18.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_18.bm new file mode 100644 index 0000000000..4f191f3190 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_18.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_19.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_19.bm new file mode 100644 index 0000000000..4e4f8f4200 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_19.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_2.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_2.bm new file mode 100644 index 0000000000..283c0b0498 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_2.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_20.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_20.bm new file mode 100644 index 0000000000..6502e0f518 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_20.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_21.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_21.bm new file mode 100644 index 0000000000..cfd887e88a Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_21.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_22.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_22.bm new file mode 100644 index 0000000000..932a22eba9 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_22.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_23.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_23.bm new file mode 100644 index 0000000000..8dcf524354 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_23.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_24.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_24.bm new file mode 100644 index 0000000000..bbce6a9ee0 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_24.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_25.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_25.bm new file mode 100644 index 0000000000..284b6a9433 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_25.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_26.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_26.bm new file mode 100644 index 0000000000..af3236d9ac Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_26.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_27.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_27.bm new file mode 100644 index 0000000000..222e52ddb2 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_27.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_28.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_28.bm new file mode 100644 index 0000000000..c593bf25c0 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_28.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_29.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_29.bm new file mode 100644 index 0000000000..f98daff7f8 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_29.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_3.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_3.bm new file mode 100644 index 0000000000..becbf66b60 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_3.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_30.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_30.bm new file mode 100644 index 0000000000..746d9492e2 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_30.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_31.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_31.bm new file mode 100644 index 0000000000..045c8f8cb0 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_31.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_32.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_32.bm new file mode 100644 index 0000000000..e059db7e94 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_32.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_33.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_33.bm new file mode 100644 index 0000000000..fe4fc62e66 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_33.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_34.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_34.bm new file mode 100644 index 0000000000..763c9dadcc Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_34.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_35.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_35.bm new file mode 100644 index 0000000000..e5719da447 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_35.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_36.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_36.bm new file mode 100644 index 0000000000..8ae13fa73e Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_36.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_37.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_37.bm new file mode 100644 index 0000000000..103e36cae0 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_37.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_38.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_38.bm new file mode 100644 index 0000000000..855b6d8e3e Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_38.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_39.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_39.bm new file mode 100644 index 0000000000..d544b12e02 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_39.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_4.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_4.bm new file mode 100644 index 0000000000..9f28cb127c Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_4.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_40.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_40.bm new file mode 100644 index 0000000000..f78d8af742 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_40.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_41.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_41.bm new file mode 100644 index 0000000000..1ae586f6b4 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_41.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_5.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_5.bm new file mode 100644 index 0000000000..c15de6af0d Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_5.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_6.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_6.bm new file mode 100644 index 0000000000..a1ec108fa6 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_6.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_7.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_7.bm new file mode 100644 index 0000000000..c4a05d9d04 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_7.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_8.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_8.bm new file mode 100644 index 0000000000..bb43dc48d9 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_8.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_9.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_9.bm new file mode 100644 index 0000000000..c214b4fc78 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/frame_9.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/meta.txt b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/meta.txt new file mode 100644 index 0000000000..1f2937d970 --- /dev/null +++ b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ANIM/meta.txt @@ -0,0 +1,14 @@ +Filetype: Flipper Animation +Version: 1 + +Width: 128 +Height: 64 +Passive frames: 42 +Active frames: 0 +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 +Active cycles: 0 +Frame rate: 6 +Duration: 3600 +Active cooldown: 0 + +Bubble slots: 0 diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ASCII/frame_0.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ASCII/frame_0.bm new file mode 100644 index 0000000000..1ae586f6b4 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ASCII/frame_0.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ASCII/frame_1.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ASCII/frame_1.bm new file mode 100644 index 0000000000..344975fda8 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ASCII/frame_1.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ASCII/frame_10.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ASCII/frame_10.bm new file mode 100644 index 0000000000..a1b40296c3 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ASCII/frame_10.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ASCII/frame_2.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ASCII/frame_2.bm new file mode 100644 index 0000000000..6390af889e Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ASCII/frame_2.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ASCII/frame_3.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ASCII/frame_3.bm new file mode 100644 index 0000000000..f1561ebb6c Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ASCII/frame_3.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ASCII/frame_4.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ASCII/frame_4.bm new file mode 100644 index 0000000000..34847a1819 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ASCII/frame_4.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ASCII/frame_5.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ASCII/frame_5.bm new file mode 100644 index 0000000000..b635bf3e45 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ASCII/frame_5.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ASCII/frame_6.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ASCII/frame_6.bm new file mode 100644 index 0000000000..86ade632b0 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ASCII/frame_6.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ASCII/frame_7.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ASCII/frame_7.bm new file mode 100644 index 0000000000..3659bd9605 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ASCII/frame_7.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ASCII/frame_8.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ASCII/frame_8.bm new file mode 100644 index 0000000000..f8dfa729e8 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ASCII/frame_8.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ASCII/frame_9.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ASCII/frame_9.bm new file mode 100644 index 0000000000..77cbb5a7ce Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ASCII/frame_9.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ASCII/meta.txt b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ASCII/meta.txt new file mode 100644 index 0000000000..c601480501 --- /dev/null +++ b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_ASCII/meta.txt @@ -0,0 +1,14 @@ +Filetype: Flipper Animation +Version: 1 + +Width: 128 +Height: 64 +Passive frames: 11 +Active frames: 0 +Frames order: 0 1 2 3 4 5 6 7 8 9 10 +Active cycles: 0 +Frame rate: 4 +Duration: 3600 +Active cooldown: 0 + +Bubble slots: 0 diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_0.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_0.bm new file mode 100644 index 0000000000..086b1eb142 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_0.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_1.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_1.bm new file mode 100644 index 0000000000..d8a0d39ccf Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_1.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_10.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_10.bm new file mode 100644 index 0000000000..9a30f1c0e7 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_10.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_11.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_11.bm new file mode 100644 index 0000000000..035dd2dd5b Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_11.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_12.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_12.bm new file mode 100644 index 0000000000..15fb3b32fc Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_12.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_13.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_13.bm new file mode 100644 index 0000000000..f6e6c65526 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_13.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_14.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_14.bm new file mode 100644 index 0000000000..b29332e8ea Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_14.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_15.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_15.bm new file mode 100644 index 0000000000..edb5c747d5 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_15.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_16.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_16.bm new file mode 100644 index 0000000000..f45e18db02 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_16.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_17.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_17.bm new file mode 100644 index 0000000000..53058983f6 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_17.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_18.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_18.bm new file mode 100644 index 0000000000..c365a0cd27 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_18.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_19.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_19.bm new file mode 100644 index 0000000000..0eab7df0ed Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_19.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_2.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_2.bm new file mode 100644 index 0000000000..ca6972e98b Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_2.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_20.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_20.bm new file mode 100644 index 0000000000..d2aa55398f Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_20.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_21.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_21.bm new file mode 100644 index 0000000000..71d0b27090 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_21.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_22.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_22.bm new file mode 100644 index 0000000000..eacbae7117 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_22.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_23.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_23.bm new file mode 100644 index 0000000000..8f06f99bf5 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_23.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_24.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_24.bm new file mode 100644 index 0000000000..2677c37a11 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_24.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_25.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_25.bm new file mode 100644 index 0000000000..f43d328727 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_25.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_26.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_26.bm new file mode 100644 index 0000000000..e5e8238687 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_26.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_27.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_27.bm new file mode 100644 index 0000000000..197b43a82a Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_27.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_28.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_28.bm new file mode 100644 index 0000000000..392e2f9582 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_28.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_29.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_29.bm new file mode 100644 index 0000000000..7affdf3f3c Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_29.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_3.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_3.bm new file mode 100644 index 0000000000..1fafbb9c58 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_3.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_30.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_30.bm new file mode 100644 index 0000000000..20ce058a1e Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_30.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_31.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_31.bm new file mode 100644 index 0000000000..a3d03a42cc Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_31.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_4.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_4.bm new file mode 100644 index 0000000000..d4fd6cb06a Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_4.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_5.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_5.bm new file mode 100644 index 0000000000..8e7fae88f3 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_5.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_6.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_6.bm new file mode 100644 index 0000000000..fa7f1f7cf5 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_6.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_7.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_7.bm new file mode 100644 index 0000000000..08c465af44 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_7.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_8.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_8.bm new file mode 100644 index 0000000000..f98a03e59b Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_8.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_9.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_9.bm new file mode 100644 index 0000000000..f49f03475c Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/frame_9.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/meta.txt b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/meta.txt new file mode 100644 index 0000000000..64a5c94655 --- /dev/null +++ b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_LOGO/meta.txt @@ -0,0 +1,14 @@ +Filetype: Flipper Animation +Version: 1 + +Width: 128 +Height: 64 +Passive frames: 32 +Active frames: 0 +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 +Active cycles: 0 +Frame rate: 5 +Duration: 3600 +Active cooldown: 0 + +Bubble slots: 0 diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_OLD/frame_0.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_OLD/frame_0.bm new file mode 100644 index 0000000000..0d12638dbf Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_OLD/frame_0.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_OLD/frame_1.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_OLD/frame_1.bm new file mode 100644 index 0000000000..c11f04ac51 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_OLD/frame_1.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_OLD/frame_10.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_OLD/frame_10.bm new file mode 100644 index 0000000000..150620b28f Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_OLD/frame_10.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_OLD/frame_11.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_OLD/frame_11.bm new file mode 100644 index 0000000000..133f9e6556 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_OLD/frame_11.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_OLD/frame_12.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_OLD/frame_12.bm new file mode 100644 index 0000000000..0760c714f4 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_OLD/frame_12.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_OLD/frame_13.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_OLD/frame_13.bm new file mode 100644 index 0000000000..cd65a69fc9 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_OLD/frame_13.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_OLD/frame_14.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_OLD/frame_14.bm new file mode 100644 index 0000000000..823be26e61 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_OLD/frame_14.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_OLD/frame_15.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_OLD/frame_15.bm new file mode 100644 index 0000000000..d520e02c0a Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_OLD/frame_15.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_OLD/frame_16.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_OLD/frame_16.bm new file mode 100644 index 0000000000..9c94e7592e Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_OLD/frame_16.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_OLD/frame_17.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_OLD/frame_17.bm new file mode 100644 index 0000000000..987e2bdc67 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_OLD/frame_17.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_OLD/frame_18.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_OLD/frame_18.bm new file mode 100644 index 0000000000..d520e02c0a Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_OLD/frame_18.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_OLD/frame_19.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_OLD/frame_19.bm new file mode 100644 index 0000000000..823be26e61 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_OLD/frame_19.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_OLD/frame_2.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_OLD/frame_2.bm new file mode 100644 index 0000000000..47b7ac4bfc Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_OLD/frame_2.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_OLD/frame_20.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_OLD/frame_20.bm new file mode 100644 index 0000000000..d520e02c0a Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_OLD/frame_20.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_OLD/frame_3.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_OLD/frame_3.bm new file mode 100644 index 0000000000..74796de85c Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_OLD/frame_3.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_OLD/frame_4.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_OLD/frame_4.bm new file mode 100644 index 0000000000..74796de85c Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_OLD/frame_4.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_OLD/frame_5.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_OLD/frame_5.bm new file mode 100644 index 0000000000..c90181f190 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_OLD/frame_5.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_OLD/frame_6.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_OLD/frame_6.bm new file mode 100644 index 0000000000..adb972470a Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_OLD/frame_6.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_OLD/frame_7.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_OLD/frame_7.bm new file mode 100644 index 0000000000..1ec74f9236 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_OLD/frame_7.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_OLD/frame_8.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_OLD/frame_8.bm new file mode 100644 index 0000000000..c0d53d465a Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_OLD/frame_8.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_OLD/frame_9.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_OLD/frame_9.bm new file mode 100644 index 0000000000..020a8633eb Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_OLD/frame_9.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_OLD/meta.txt b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_OLD/meta.txt new file mode 100644 index 0000000000..6dabe353ff --- /dev/null +++ b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_OLD/meta.txt @@ -0,0 +1,14 @@ +Filetype: Flipper Animation +Version: 1 + +Width: 128 +Height: 64 +Passive frames: 21 +Active frames: 0 +Frames order: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 +Active cycles: 0 +Frame rate: 4 +Duration: 3600 +Active cooldown: 0 + +Bubble slots: 0 diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_TALK/frame_0.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_TALK/frame_0.bm new file mode 100644 index 0000000000..c235da8b3e Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_TALK/frame_0.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_TALK/frame_1.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_TALK/frame_1.bm new file mode 100644 index 0000000000..af749374bf Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_TALK/frame_1.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_TALK/frame_10.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_TALK/frame_10.bm new file mode 100644 index 0000000000..655541f441 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_TALK/frame_10.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_TALK/frame_11.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_TALK/frame_11.bm new file mode 100644 index 0000000000..6e76cf15b6 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_TALK/frame_11.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_TALK/frame_12.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_TALK/frame_12.bm new file mode 100644 index 0000000000..485b9f2553 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_TALK/frame_12.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_TALK/frame_13.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_TALK/frame_13.bm new file mode 100644 index 0000000000..79381f6d58 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_TALK/frame_13.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_TALK/frame_14.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_TALK/frame_14.bm new file mode 100644 index 0000000000..3ea0b72989 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_TALK/frame_14.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_TALK/frame_15.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_TALK/frame_15.bm new file mode 100644 index 0000000000..271aca5774 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_TALK/frame_15.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_TALK/frame_16.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_TALK/frame_16.bm new file mode 100644 index 0000000000..2b5d538b39 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_TALK/frame_16.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_TALK/frame_17.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_TALK/frame_17.bm new file mode 100644 index 0000000000..3dbfae9e40 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_TALK/frame_17.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_TALK/frame_2.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_TALK/frame_2.bm new file mode 100644 index 0000000000..54d98a982e Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_TALK/frame_2.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_TALK/frame_3.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_TALK/frame_3.bm new file mode 100644 index 0000000000..35a3d5b857 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_TALK/frame_3.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_TALK/frame_4.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_TALK/frame_4.bm new file mode 100644 index 0000000000..897cb76271 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_TALK/frame_4.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_TALK/frame_5.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_TALK/frame_5.bm new file mode 100644 index 0000000000..f3e953859f Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_TALK/frame_5.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_TALK/frame_6.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_TALK/frame_6.bm new file mode 100644 index 0000000000..f3a2e76c01 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_TALK/frame_6.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_TALK/frame_7.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_TALK/frame_7.bm new file mode 100644 index 0000000000..f12e601bec Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_TALK/frame_7.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_TALK/frame_8.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_TALK/frame_8.bm new file mode 100644 index 0000000000..3e87bc0fd2 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_TALK/frame_8.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_TALK/frame_9.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_TALK/frame_9.bm new file mode 100644 index 0000000000..5a3fa2a442 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_TALK/frame_9.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_TALK/meta.txt b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_TALK/meta.txt new file mode 100644 index 0000000000..e92e595306 --- /dev/null +++ b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_TALK/meta.txt @@ -0,0 +1,14 @@ +Filetype: Flipper Animation +Version: 1 + +Width: 128 +Height: 64 +Passive frames: 18 +Active frames: 0 +Frames order: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 +Active cycles: 0 +Frame rate: 4 +Duration: 3600 +Active cooldown: 0 + +Bubble slots: 0 diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_WAVE/frame_0.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_WAVE/frame_0.bm new file mode 100644 index 0000000000..fbce15c5fd Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_WAVE/frame_0.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_WAVE/frame_1.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_WAVE/frame_1.bm new file mode 100644 index 0000000000..20506532a5 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_WAVE/frame_1.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_WAVE/frame_10.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_WAVE/frame_10.bm new file mode 100644 index 0000000000..cf48d21d4b Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_WAVE/frame_10.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_WAVE/frame_11.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_WAVE/frame_11.bm new file mode 100644 index 0000000000..cfeda3a0c7 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_WAVE/frame_11.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_WAVE/frame_12.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_WAVE/frame_12.bm new file mode 100644 index 0000000000..4e5e60b7f9 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_WAVE/frame_12.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_WAVE/frame_13.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_WAVE/frame_13.bm new file mode 100644 index 0000000000..30b9da7645 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_WAVE/frame_13.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_WAVE/frame_14.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_WAVE/frame_14.bm new file mode 100644 index 0000000000..5dd9e71928 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_WAVE/frame_14.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_WAVE/frame_15.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_WAVE/frame_15.bm new file mode 100644 index 0000000000..d9800786ea Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_WAVE/frame_15.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_WAVE/frame_2.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_WAVE/frame_2.bm new file mode 100644 index 0000000000..f1eb1199b4 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_WAVE/frame_2.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_WAVE/frame_3.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_WAVE/frame_3.bm new file mode 100644 index 0000000000..bd7f253acb Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_WAVE/frame_3.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_WAVE/frame_4.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_WAVE/frame_4.bm new file mode 100644 index 0000000000..0e2aaa31d2 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_WAVE/frame_4.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_WAVE/frame_5.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_WAVE/frame_5.bm new file mode 100644 index 0000000000..f5619c8276 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_WAVE/frame_5.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_WAVE/frame_6.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_WAVE/frame_6.bm new file mode 100644 index 0000000000..c5a80f216c Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_WAVE/frame_6.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_WAVE/frame_7.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_WAVE/frame_7.bm new file mode 100644 index 0000000000..c5e5775621 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_WAVE/frame_7.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_WAVE/frame_8.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_WAVE/frame_8.bm new file mode 100644 index 0000000000..7236bcccdb Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_WAVE/frame_8.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_WAVE/frame_9.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_WAVE/frame_9.bm new file mode 100644 index 0000000000..aabdf52eb6 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_WAVE/frame_9.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_WAVE/meta.txt b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_WAVE/meta.txt new file mode 100644 index 0000000000..55dd3ae55f --- /dev/null +++ b/assets/resources/dolphin_custom/WatchDogs/Anims/DEDSEC_WAVE/meta.txt @@ -0,0 +1,14 @@ +Filetype: Flipper Animation +Version: 1 + +Width: 128 +Height: 64 +Passive frames: 16 +Active frames: 0 +Frames order: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 +Active cycles: 0 +Frame rate: 7 +Duration: 3600 +Active cooldown: 0 + +Bubble slots: 0 diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/FINGER/frame_0.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/FINGER/frame_0.bm new file mode 100644 index 0000000000..5f0b5e8572 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/FINGER/frame_0.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/FINGER/frame_1.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/FINGER/frame_1.bm new file mode 100644 index 0000000000..4e78225930 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/FINGER/frame_1.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/FINGER/frame_2.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/FINGER/frame_2.bm new file mode 100644 index 0000000000..847684fe1a Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/FINGER/frame_2.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/FINGER/frame_3.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/FINGER/frame_3.bm new file mode 100644 index 0000000000..bd9754c869 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/FINGER/frame_3.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/FINGER/meta.txt b/assets/resources/dolphin_custom/WatchDogs/Anims/FINGER/meta.txt new file mode 100644 index 0000000000..118db3cbed --- /dev/null +++ b/assets/resources/dolphin_custom/WatchDogs/Anims/FINGER/meta.txt @@ -0,0 +1,14 @@ +Filetype: Flipper Animation +Version: 1 + +Width: 128 +Height: 64 +Passive frames: 6 +Active frames: 0 +Frames order: 0 1 2 3 2 3 +Active cycles: 0 +Frame rate: 2 +Duration: 3600 +Active cooldown: 0 + +Bubble slots: 0 diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/GUNS_CAR/frame_0.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/GUNS_CAR/frame_0.bm new file mode 100644 index 0000000000..0b8467a675 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/GUNS_CAR/frame_0.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/GUNS_CAR/frame_1.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/GUNS_CAR/frame_1.bm new file mode 100644 index 0000000000..2f758e8095 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/GUNS_CAR/frame_1.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/GUNS_CAR/frame_10.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/GUNS_CAR/frame_10.bm new file mode 100644 index 0000000000..bf330ea684 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/GUNS_CAR/frame_10.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/GUNS_CAR/frame_11.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/GUNS_CAR/frame_11.bm new file mode 100644 index 0000000000..7373852c90 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/GUNS_CAR/frame_11.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/GUNS_CAR/frame_12.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/GUNS_CAR/frame_12.bm new file mode 100644 index 0000000000..9294505efa Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/GUNS_CAR/frame_12.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/GUNS_CAR/frame_13.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/GUNS_CAR/frame_13.bm new file mode 100644 index 0000000000..68843f2de5 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/GUNS_CAR/frame_13.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/GUNS_CAR/frame_14.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/GUNS_CAR/frame_14.bm new file mode 100644 index 0000000000..015477cc80 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/GUNS_CAR/frame_14.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/GUNS_CAR/frame_15.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/GUNS_CAR/frame_15.bm new file mode 100644 index 0000000000..7afbcf2d07 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/GUNS_CAR/frame_15.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/GUNS_CAR/frame_16.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/GUNS_CAR/frame_16.bm new file mode 100644 index 0000000000..7aca67d010 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/GUNS_CAR/frame_16.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/GUNS_CAR/frame_17.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/GUNS_CAR/frame_17.bm new file mode 100644 index 0000000000..e3b633199b Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/GUNS_CAR/frame_17.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/GUNS_CAR/frame_18.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/GUNS_CAR/frame_18.bm new file mode 100644 index 0000000000..a757185135 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/GUNS_CAR/frame_18.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/GUNS_CAR/frame_19.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/GUNS_CAR/frame_19.bm new file mode 100644 index 0000000000..02985b127b Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/GUNS_CAR/frame_19.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/GUNS_CAR/frame_2.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/GUNS_CAR/frame_2.bm new file mode 100644 index 0000000000..845a0c5b44 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/GUNS_CAR/frame_2.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/GUNS_CAR/frame_20.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/GUNS_CAR/frame_20.bm new file mode 100644 index 0000000000..977e89ace7 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/GUNS_CAR/frame_20.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/GUNS_CAR/frame_21.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/GUNS_CAR/frame_21.bm new file mode 100644 index 0000000000..fdf80ff6d2 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/GUNS_CAR/frame_21.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/GUNS_CAR/frame_3.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/GUNS_CAR/frame_3.bm new file mode 100644 index 0000000000..bf0e5506ee Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/GUNS_CAR/frame_3.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/GUNS_CAR/frame_4.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/GUNS_CAR/frame_4.bm new file mode 100644 index 0000000000..7bde41d8a8 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/GUNS_CAR/frame_4.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/GUNS_CAR/frame_5.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/GUNS_CAR/frame_5.bm new file mode 100644 index 0000000000..faa5636d23 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/GUNS_CAR/frame_5.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/GUNS_CAR/frame_6.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/GUNS_CAR/frame_6.bm new file mode 100644 index 0000000000..3137638f3a Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/GUNS_CAR/frame_6.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/GUNS_CAR/frame_7.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/GUNS_CAR/frame_7.bm new file mode 100644 index 0000000000..94f7767d30 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/GUNS_CAR/frame_7.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/GUNS_CAR/frame_8.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/GUNS_CAR/frame_8.bm new file mode 100644 index 0000000000..5efea1a32e Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/GUNS_CAR/frame_8.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/GUNS_CAR/frame_9.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/GUNS_CAR/frame_9.bm new file mode 100644 index 0000000000..d9b7a21d4d Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/GUNS_CAR/frame_9.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/GUNS_CAR/meta.txt b/assets/resources/dolphin_custom/WatchDogs/Anims/GUNS_CAR/meta.txt new file mode 100644 index 0000000000..8fe58cec3f --- /dev/null +++ b/assets/resources/dolphin_custom/WatchDogs/Anims/GUNS_CAR/meta.txt @@ -0,0 +1,14 @@ +Filetype: Flipper Animation +Version: 1 + +Width: 128 +Height: 64 +Passive frames: 22 +Active frames: 0 +Frames order: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 +Active cycles: 0 +Frame rate: 4 +Duration: 3600 +Active cooldown: 0 + +Bubble slots: 0 diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/HANDS/frame_0.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/HANDS/frame_0.bm new file mode 100644 index 0000000000..34f3ce2fdb Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/HANDS/frame_0.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/HANDS/frame_1.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/HANDS/frame_1.bm new file mode 100644 index 0000000000..923913d01a Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/HANDS/frame_1.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/HANDS/frame_2.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/HANDS/frame_2.bm new file mode 100644 index 0000000000..96039803a2 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/HANDS/frame_2.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/HANDS/frame_3.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/HANDS/frame_3.bm new file mode 100644 index 0000000000..d6d29304ed Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/HANDS/frame_3.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/HANDS/frame_4.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/HANDS/frame_4.bm new file mode 100644 index 0000000000..e223a7590c Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/HANDS/frame_4.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/HANDS/frame_5.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/HANDS/frame_5.bm new file mode 100644 index 0000000000..ec7dc02011 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/HANDS/frame_5.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/HANDS/frame_6.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/HANDS/frame_6.bm new file mode 100644 index 0000000000..dc0ab47a74 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/HANDS/frame_6.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/HANDS/meta.txt b/assets/resources/dolphin_custom/WatchDogs/Anims/HANDS/meta.txt new file mode 100644 index 0000000000..f83c9071bf --- /dev/null +++ b/assets/resources/dolphin_custom/WatchDogs/Anims/HANDS/meta.txt @@ -0,0 +1,14 @@ +Filetype: Flipper Animation +Version: 1 + +Width: 128 +Height: 64 +Passive frames: 12 +Active frames: 0 +Frames order: 0 1 2 3 4 5 6 5 4 3 2 1 +Active cycles: 0 +Frame rate: 4 +Duration: 3600 +Active cooldown: 0 + +Bubble slots: 0 diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/JOIN_US/frame_0.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/JOIN_US/frame_0.bm new file mode 100644 index 0000000000..57386557ab Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/JOIN_US/frame_0.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/JOIN_US/frame_1.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/JOIN_US/frame_1.bm new file mode 100644 index 0000000000..d421106f07 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/JOIN_US/frame_1.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/JOIN_US/meta.txt b/assets/resources/dolphin_custom/WatchDogs/Anims/JOIN_US/meta.txt new file mode 100644 index 0000000000..10961ac36a --- /dev/null +++ b/assets/resources/dolphin_custom/WatchDogs/Anims/JOIN_US/meta.txt @@ -0,0 +1,14 @@ +Filetype: Flipper Animation +Version: 1 + +Width: 128 +Height: 64 +Passive frames: 2 +Active frames: 0 +Frames order: 0 1 +Active cycles: 0 +Frame rate: 2 +Duration: 3600 +Active cooldown: 0 + +Bubble slots: 0 diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_0.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_0.bm new file mode 100644 index 0000000000..1ae586f6b4 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_0.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_1.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_1.bm new file mode 100644 index 0000000000..1ae586f6b4 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_1.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_10.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_10.bm new file mode 100644 index 0000000000..4a54e9bcd7 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_10.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_11.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_11.bm new file mode 100644 index 0000000000..9d16114e9c Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_11.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_12.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_12.bm new file mode 100644 index 0000000000..73ce2b4a24 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_12.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_13.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_13.bm new file mode 100644 index 0000000000..fb6a846c53 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_13.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_14.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_14.bm new file mode 100644 index 0000000000..3ad30a15f9 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_14.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_15.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_15.bm new file mode 100644 index 0000000000..13d01fdb1c Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_15.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_16.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_16.bm new file mode 100644 index 0000000000..58062e238c Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_16.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_17.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_17.bm new file mode 100644 index 0000000000..d8fbae8374 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_17.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_18.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_18.bm new file mode 100644 index 0000000000..46d67e836a Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_18.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_19.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_19.bm new file mode 100644 index 0000000000..330f265809 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_19.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_2.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_2.bm new file mode 100644 index 0000000000..63cb62e7a2 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_2.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_20.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_20.bm new file mode 100644 index 0000000000..2496932c6e Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_20.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_21.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_21.bm new file mode 100644 index 0000000000..914abe79b4 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_21.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_22.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_22.bm new file mode 100644 index 0000000000..33635a4a83 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_22.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_23.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_23.bm new file mode 100644 index 0000000000..97900cd742 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_23.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_24.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_24.bm new file mode 100644 index 0000000000..1ae586f6b4 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_24.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_25.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_25.bm new file mode 100644 index 0000000000..5338ea1174 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_25.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_26.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_26.bm new file mode 100644 index 0000000000..1ae586f6b4 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_26.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_27.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_27.bm new file mode 100644 index 0000000000..1ae586f6b4 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_27.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_28.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_28.bm new file mode 100644 index 0000000000..635280724d Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_28.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_29.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_29.bm new file mode 100644 index 0000000000..1ae586f6b4 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_29.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_3.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_3.bm new file mode 100644 index 0000000000..b3ad32b4a9 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_3.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_30.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_30.bm new file mode 100644 index 0000000000..1ae586f6b4 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_30.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_4.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_4.bm new file mode 100644 index 0000000000..1ae586f6b4 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_4.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_5.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_5.bm new file mode 100644 index 0000000000..c84b750702 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_5.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_6.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_6.bm new file mode 100644 index 0000000000..d591e31c01 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_6.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_7.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_7.bm new file mode 100644 index 0000000000..e13d342500 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_7.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_8.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_8.bm new file mode 100644 index 0000000000..e7e9d03176 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_8.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_9.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_9.bm new file mode 100644 index 0000000000..0fcac4257a Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/frame_9.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/meta.txt b/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/meta.txt new file mode 100644 index 0000000000..305463c192 --- /dev/null +++ b/assets/resources/dolphin_custom/WatchDogs/Anims/LOGO_WD2/meta.txt @@ -0,0 +1,14 @@ +Filetype: Flipper Animation +Version: 1 + +Width: 128 +Height: 64 +Passive frames: 31 +Active frames: 0 +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 +Active cycles: 0 +Frame rate: 4 +Duration: 3600 +Active cooldown: 0 + +Bubble slots: 0 diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/MARCUS/frame_0.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/MARCUS/frame_0.bm new file mode 100644 index 0000000000..8b5e072060 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/MARCUS/frame_0.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/MARCUS/frame_1.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/MARCUS/frame_1.bm new file mode 100644 index 0000000000..3307b2680b Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/MARCUS/frame_1.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/MARCUS/frame_10.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/MARCUS/frame_10.bm new file mode 100644 index 0000000000..b6d84d4c17 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/MARCUS/frame_10.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/MARCUS/frame_11.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/MARCUS/frame_11.bm new file mode 100644 index 0000000000..87ffd215e2 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/MARCUS/frame_11.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/MARCUS/frame_12.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/MARCUS/frame_12.bm new file mode 100644 index 0000000000..65bd6a5aa7 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/MARCUS/frame_12.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/MARCUS/frame_13.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/MARCUS/frame_13.bm new file mode 100644 index 0000000000..54d3107efc Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/MARCUS/frame_13.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/MARCUS/frame_14.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/MARCUS/frame_14.bm new file mode 100644 index 0000000000..e3333c0e8b Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/MARCUS/frame_14.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/MARCUS/frame_15.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/MARCUS/frame_15.bm new file mode 100644 index 0000000000..1811bfb3da Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/MARCUS/frame_15.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/MARCUS/frame_16.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/MARCUS/frame_16.bm new file mode 100644 index 0000000000..ddd1d23954 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/MARCUS/frame_16.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/MARCUS/frame_17.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/MARCUS/frame_17.bm new file mode 100644 index 0000000000..ffee017ade Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/MARCUS/frame_17.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/MARCUS/frame_18.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/MARCUS/frame_18.bm new file mode 100644 index 0000000000..f663860233 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/MARCUS/frame_18.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/MARCUS/frame_19.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/MARCUS/frame_19.bm new file mode 100644 index 0000000000..47f3ec1fe1 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/MARCUS/frame_19.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/MARCUS/frame_2.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/MARCUS/frame_2.bm new file mode 100644 index 0000000000..9160a850e9 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/MARCUS/frame_2.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/MARCUS/frame_20.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/MARCUS/frame_20.bm new file mode 100644 index 0000000000..5a86d581e1 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/MARCUS/frame_20.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/MARCUS/frame_21.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/MARCUS/frame_21.bm new file mode 100644 index 0000000000..02782bb77a Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/MARCUS/frame_21.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/MARCUS/frame_22.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/MARCUS/frame_22.bm new file mode 100644 index 0000000000..defb712b9b Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/MARCUS/frame_22.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/MARCUS/frame_23.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/MARCUS/frame_23.bm new file mode 100644 index 0000000000..f91ebaa1ca Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/MARCUS/frame_23.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/MARCUS/frame_3.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/MARCUS/frame_3.bm new file mode 100644 index 0000000000..2614a9a38e Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/MARCUS/frame_3.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/MARCUS/frame_4.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/MARCUS/frame_4.bm new file mode 100644 index 0000000000..c4b03793be Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/MARCUS/frame_4.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/MARCUS/frame_5.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/MARCUS/frame_5.bm new file mode 100644 index 0000000000..8da3699ec4 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/MARCUS/frame_5.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/MARCUS/frame_6.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/MARCUS/frame_6.bm new file mode 100644 index 0000000000..9f8ffc153d Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/MARCUS/frame_6.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/MARCUS/frame_7.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/MARCUS/frame_7.bm new file mode 100644 index 0000000000..414171469a Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/MARCUS/frame_7.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/MARCUS/frame_8.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/MARCUS/frame_8.bm new file mode 100644 index 0000000000..82ca3d18a1 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/MARCUS/frame_8.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/MARCUS/frame_9.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/MARCUS/frame_9.bm new file mode 100644 index 0000000000..2c8190d328 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/MARCUS/frame_9.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/MARCUS/meta.txt b/assets/resources/dolphin_custom/WatchDogs/Anims/MARCUS/meta.txt new file mode 100644 index 0000000000..81cc6c7d92 --- /dev/null +++ b/assets/resources/dolphin_custom/WatchDogs/Anims/MARCUS/meta.txt @@ -0,0 +1,14 @@ +Filetype: Flipper Animation +Version: 1 + +Width: 128 +Height: 64 +Passive frames: 24 +Active frames: 0 +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 +Active cycles: 0 +Frame rate: 4 +Duration: 3600 +Active cooldown: 0 + +Bubble slots: 0 diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/MUMMY/frame_0.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/MUMMY/frame_0.bm new file mode 100644 index 0000000000..efb1c363cf Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/MUMMY/frame_0.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/MUMMY/frame_1.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/MUMMY/frame_1.bm new file mode 100644 index 0000000000..2344530a74 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/MUMMY/frame_1.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/MUMMY/frame_2.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/MUMMY/frame_2.bm new file mode 100644 index 0000000000..f37994b246 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/MUMMY/frame_2.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/MUMMY/frame_3.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/MUMMY/frame_3.bm new file mode 100644 index 0000000000..10de7e314c Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/MUMMY/frame_3.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/MUMMY/meta.txt b/assets/resources/dolphin_custom/WatchDogs/Anims/MUMMY/meta.txt new file mode 100644 index 0000000000..1ede667459 --- /dev/null +++ b/assets/resources/dolphin_custom/WatchDogs/Anims/MUMMY/meta.txt @@ -0,0 +1,23 @@ +Filetype: Flipper Animation +Version: 1 + +Width: 128 +Height: 64 +Passive frames: 5 +Active frames: 4 +Frames order: 2 0 1 3 0 2 3 2 3 +Active cycles: 2 +Frame rate: 2 +Duration: 3600 +Active cooldown: 1 + +Bubble slots: 1 + +Slot: 0 +X: 27 +Y: 24 +Text: AARGH! +AlignH: Right +AlignV: Center +StartFrame: 6 +EndFrame: 9 diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_0.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_0.bm new file mode 100644 index 0000000000..4f1f6df42a Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_0.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_1.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_1.bm new file mode 100644 index 0000000000..0f143aa37f Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_1.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_10.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_10.bm new file mode 100644 index 0000000000..360c342ba8 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_10.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_11.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_11.bm new file mode 100644 index 0000000000..5a27175f36 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_11.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_12.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_12.bm new file mode 100644 index 0000000000..94a5d826bf Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_12.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_13.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_13.bm new file mode 100644 index 0000000000..b663cb8b43 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_13.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_14.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_14.bm new file mode 100644 index 0000000000..d6c68c61d2 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_14.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_15.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_15.bm new file mode 100644 index 0000000000..03d2a06ecb Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_15.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_16.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_16.bm new file mode 100644 index 0000000000..bb78af916a Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_16.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_17.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_17.bm new file mode 100644 index 0000000000..832b7f5aa2 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_17.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_18.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_18.bm new file mode 100644 index 0000000000..ecc8c83989 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_18.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_19.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_19.bm new file mode 100644 index 0000000000..9fb6b3a05b Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_19.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_2.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_2.bm new file mode 100644 index 0000000000..adeec6abbd Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_2.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_20.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_20.bm new file mode 100644 index 0000000000..d5af130f8d Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_20.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_21.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_21.bm new file mode 100644 index 0000000000..289c5d0c63 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_21.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_22.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_22.bm new file mode 100644 index 0000000000..3acfddaaf2 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_22.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_23.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_23.bm new file mode 100644 index 0000000000..ff169e3f96 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_23.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_24.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_24.bm new file mode 100644 index 0000000000..6122c3ca87 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_24.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_25.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_25.bm new file mode 100644 index 0000000000..6ac18403a6 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_25.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_26.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_26.bm new file mode 100644 index 0000000000..1dd82abce1 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_26.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_27.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_27.bm new file mode 100644 index 0000000000..47d55ee39d Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_27.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_28.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_28.bm new file mode 100644 index 0000000000..91ae349887 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_28.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_29.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_29.bm new file mode 100644 index 0000000000..2cb729c5f3 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_29.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_3.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_3.bm new file mode 100644 index 0000000000..06c257f124 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_3.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_30.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_30.bm new file mode 100644 index 0000000000..1ae586f6b4 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_30.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_31.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_31.bm new file mode 100644 index 0000000000..1ae586f6b4 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_31.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_4.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_4.bm new file mode 100644 index 0000000000..26a26f12f8 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_4.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_5.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_5.bm new file mode 100644 index 0000000000..ceb66aa022 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_5.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_6.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_6.bm new file mode 100644 index 0000000000..a29145be21 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_6.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_7.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_7.bm new file mode 100644 index 0000000000..99b6dd4e52 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_7.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_8.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_8.bm new file mode 100644 index 0000000000..603e4cf090 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_8.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_9.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_9.bm new file mode 100644 index 0000000000..bb78977d6f Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/frame_9.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/meta.txt b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/meta.txt new file mode 100644 index 0000000000..64a5c94655 --- /dev/null +++ b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER/meta.txt @@ -0,0 +1,14 @@ +Filetype: Flipper Animation +Version: 1 + +Width: 128 +Height: 64 +Passive frames: 32 +Active frames: 0 +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 +Active cycles: 0 +Frame rate: 5 +Duration: 3600 +Active cooldown: 0 + +Bubble slots: 0 diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_0.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_0.bm new file mode 100644 index 0000000000..25ac0f28a2 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_0.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_1.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_1.bm new file mode 100644 index 0000000000..a540fee584 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_1.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_10.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_10.bm new file mode 100644 index 0000000000..37bd49766d Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_10.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_11.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_11.bm new file mode 100644 index 0000000000..829568563f Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_11.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_12.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_12.bm new file mode 100644 index 0000000000..50a6809f79 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_12.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_13.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_13.bm new file mode 100644 index 0000000000..1fe9dec8a8 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_13.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_14.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_14.bm new file mode 100644 index 0000000000..9153ec32b8 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_14.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_15.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_15.bm new file mode 100644 index 0000000000..e1544cecc1 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_15.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_16.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_16.bm new file mode 100644 index 0000000000..598b4a7d9f Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_16.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_17.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_17.bm new file mode 100644 index 0000000000..4c24f3458b Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_17.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_18.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_18.bm new file mode 100644 index 0000000000..f8d52d615a Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_18.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_19.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_19.bm new file mode 100644 index 0000000000..384f3ef2a0 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_19.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_2.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_2.bm new file mode 100644 index 0000000000..d376a31b6b Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_2.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_20.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_20.bm new file mode 100644 index 0000000000..3eb8fd5a05 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_20.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_21.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_21.bm new file mode 100644 index 0000000000..3db7943c52 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_21.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_22.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_22.bm new file mode 100644 index 0000000000..da38898087 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_22.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_23.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_23.bm new file mode 100644 index 0000000000..4e6092af4c Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_23.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_24.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_24.bm new file mode 100644 index 0000000000..9d3b392da6 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_24.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_25.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_25.bm new file mode 100644 index 0000000000..080e8e11ac Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_25.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_26.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_26.bm new file mode 100644 index 0000000000..65253bc6b7 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_26.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_27.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_27.bm new file mode 100644 index 0000000000..f0a3ff5dd0 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_27.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_28.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_28.bm new file mode 100644 index 0000000000..920e8b6243 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_28.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_29.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_29.bm new file mode 100644 index 0000000000..298dfcfc34 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_29.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_3.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_3.bm new file mode 100644 index 0000000000..256969c113 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_3.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_30.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_30.bm new file mode 100644 index 0000000000..9e5b76f20e Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_30.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_31.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_31.bm new file mode 100644 index 0000000000..b2624e125d Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_31.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_32.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_32.bm new file mode 100644 index 0000000000..b4372661de Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_32.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_33.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_33.bm new file mode 100644 index 0000000000..7c2dc44842 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_33.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_34.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_34.bm new file mode 100644 index 0000000000..e5c9505f74 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_34.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_35.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_35.bm new file mode 100644 index 0000000000..22c1f70c0c Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_35.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_36.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_36.bm new file mode 100644 index 0000000000..daa2562ac5 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_36.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_37.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_37.bm new file mode 100644 index 0000000000..b7c22d6e42 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_37.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_38.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_38.bm new file mode 100644 index 0000000000..65e22129b7 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_38.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_39.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_39.bm new file mode 100644 index 0000000000..9dcf86011b Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_39.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_4.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_4.bm new file mode 100644 index 0000000000..a42df62630 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_4.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_40.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_40.bm new file mode 100644 index 0000000000..919881709c Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_40.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_41.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_41.bm new file mode 100644 index 0000000000..cee83c68a7 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_41.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_5.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_5.bm new file mode 100644 index 0000000000..d673c735e4 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_5.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_6.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_6.bm new file mode 100644 index 0000000000..ab0c9511dc Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_6.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_7.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_7.bm new file mode 100644 index 0000000000..5996918a26 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_7.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_8.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_8.bm new file mode 100644 index 0000000000..752841ad4a Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_8.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_9.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_9.bm new file mode 100644 index 0000000000..33b1d36311 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/frame_9.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/meta.txt b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/meta.txt new file mode 100644 index 0000000000..d3a51de2f1 --- /dev/null +++ b/assets/resources/dolphin_custom/WatchDogs/Anims/REAPER_ALT/meta.txt @@ -0,0 +1,14 @@ +Filetype: Flipper Animation +Version: 1 + +Width: 128 +Height: 64 +Passive frames: 28 +Active frames: 0 +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 +Active cycles: 0 +Frame rate: 4 +Duration: 3600 +Active cooldown: 0 + +Bubble slots: 0 diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL/frame_0.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL/frame_0.bm new file mode 100644 index 0000000000..9716832433 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL/frame_0.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL/frame_1.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL/frame_1.bm new file mode 100644 index 0000000000..95479906b2 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL/frame_1.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL/frame_10.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL/frame_10.bm new file mode 100644 index 0000000000..58575e8d06 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL/frame_10.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL/frame_11.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL/frame_11.bm new file mode 100644 index 0000000000..d2fd05476a Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL/frame_11.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL/frame_12.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL/frame_12.bm new file mode 100644 index 0000000000..ad76427f52 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL/frame_12.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL/frame_13.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL/frame_13.bm new file mode 100644 index 0000000000..c3469277a4 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL/frame_13.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL/frame_14.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL/frame_14.bm new file mode 100644 index 0000000000..477aed5f12 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL/frame_14.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL/frame_15.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL/frame_15.bm new file mode 100644 index 0000000000..57c0b36cdf Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL/frame_15.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL/frame_16.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL/frame_16.bm new file mode 100644 index 0000000000..8cf91760aa Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL/frame_16.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL/frame_17.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL/frame_17.bm new file mode 100644 index 0000000000..ee40242317 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL/frame_17.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL/frame_18.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL/frame_18.bm new file mode 100644 index 0000000000..8c3b6eb3d8 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL/frame_18.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL/frame_19.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL/frame_19.bm new file mode 100644 index 0000000000..ffa9a7d96e Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL/frame_19.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL/frame_2.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL/frame_2.bm new file mode 100644 index 0000000000..e4ca0bd0d6 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL/frame_2.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL/frame_20.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL/frame_20.bm new file mode 100644 index 0000000000..c979d35bb3 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL/frame_20.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL/frame_21.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL/frame_21.bm new file mode 100644 index 0000000000..e270d6fcf6 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL/frame_21.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL/frame_22.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL/frame_22.bm new file mode 100644 index 0000000000..8e69e35e29 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL/frame_22.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL/frame_23.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL/frame_23.bm new file mode 100644 index 0000000000..732d7e62bc Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL/frame_23.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL/frame_24.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL/frame_24.bm new file mode 100644 index 0000000000..0044ffd382 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL/frame_24.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL/frame_25.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL/frame_25.bm new file mode 100644 index 0000000000..82c4214c7e Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL/frame_25.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL/frame_26.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL/frame_26.bm new file mode 100644 index 0000000000..7db1d43b42 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL/frame_26.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL/frame_3.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL/frame_3.bm new file mode 100644 index 0000000000..93122e7b24 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL/frame_3.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL/frame_4.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL/frame_4.bm new file mode 100644 index 0000000000..9578a05ca5 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL/frame_4.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL/frame_5.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL/frame_5.bm new file mode 100644 index 0000000000..7f6c1aff09 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL/frame_5.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL/frame_6.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL/frame_6.bm new file mode 100644 index 0000000000..aadc3728ad Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL/frame_6.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL/frame_7.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL/frame_7.bm new file mode 100644 index 0000000000..3592d70043 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL/frame_7.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL/frame_8.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL/frame_8.bm new file mode 100644 index 0000000000..4dc0cf0f0b Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL/frame_8.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL/frame_9.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL/frame_9.bm new file mode 100644 index 0000000000..dc812795ff Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL/frame_9.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL/meta.txt b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL/meta.txt new file mode 100644 index 0000000000..1ca66ff130 --- /dev/null +++ b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL/meta.txt @@ -0,0 +1,14 @@ +Filetype: Flipper Animation +Version: 1 + +Width: 128 +Height: 64 +Passive frames: 27 +Active frames: 0 +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 +Active cycles: 0 +Frame rate: 4 +Duration: 3600 +Active cooldown: 0 + +Bubble slots: 0 diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL_SPIN/frame_0.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL_SPIN/frame_0.bm new file mode 100644 index 0000000000..4e85158cee Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL_SPIN/frame_0.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL_SPIN/frame_1.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL_SPIN/frame_1.bm new file mode 100644 index 0000000000..ab39152e30 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL_SPIN/frame_1.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL_SPIN/frame_10.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL_SPIN/frame_10.bm new file mode 100644 index 0000000000..f577ce9704 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL_SPIN/frame_10.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL_SPIN/frame_11.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL_SPIN/frame_11.bm new file mode 100644 index 0000000000..01a8f7b365 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL_SPIN/frame_11.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL_SPIN/frame_12.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL_SPIN/frame_12.bm new file mode 100644 index 0000000000..905fa2ca7c Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL_SPIN/frame_12.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL_SPIN/frame_13.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL_SPIN/frame_13.bm new file mode 100644 index 0000000000..65880dc89c Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL_SPIN/frame_13.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL_SPIN/frame_14.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL_SPIN/frame_14.bm new file mode 100644 index 0000000000..35cc235580 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL_SPIN/frame_14.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL_SPIN/frame_15.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL_SPIN/frame_15.bm new file mode 100644 index 0000000000..960b1bd69c Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL_SPIN/frame_15.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL_SPIN/frame_16.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL_SPIN/frame_16.bm new file mode 100644 index 0000000000..314b6399a9 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL_SPIN/frame_16.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL_SPIN/frame_17.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL_SPIN/frame_17.bm new file mode 100644 index 0000000000..14e0603b59 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL_SPIN/frame_17.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL_SPIN/frame_18.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL_SPIN/frame_18.bm new file mode 100644 index 0000000000..f0d6bb7724 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL_SPIN/frame_18.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL_SPIN/frame_2.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL_SPIN/frame_2.bm new file mode 100644 index 0000000000..422e937544 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL_SPIN/frame_2.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL_SPIN/frame_3.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL_SPIN/frame_3.bm new file mode 100644 index 0000000000..6c1060c0bf Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL_SPIN/frame_3.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL_SPIN/frame_4.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL_SPIN/frame_4.bm new file mode 100644 index 0000000000..e25e784d9c Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL_SPIN/frame_4.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL_SPIN/frame_5.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL_SPIN/frame_5.bm new file mode 100644 index 0000000000..569a5763d8 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL_SPIN/frame_5.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL_SPIN/frame_6.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL_SPIN/frame_6.bm new file mode 100644 index 0000000000..b1ee630fb0 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL_SPIN/frame_6.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL_SPIN/frame_7.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL_SPIN/frame_7.bm new file mode 100644 index 0000000000..815067c7e6 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL_SPIN/frame_7.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL_SPIN/frame_8.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL_SPIN/frame_8.bm new file mode 100644 index 0000000000..87e06e151c Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL_SPIN/frame_8.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL_SPIN/frame_9.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL_SPIN/frame_9.bm new file mode 100644 index 0000000000..d31525b445 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL_SPIN/frame_9.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL_SPIN/meta.txt b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL_SPIN/meta.txt new file mode 100644 index 0000000000..53f5a9ef34 --- /dev/null +++ b/assets/resources/dolphin_custom/WatchDogs/Anims/SKULL_SPIN/meta.txt @@ -0,0 +1,14 @@ +Filetype: Flipper Animation +Version: 1 + +Width: 128 +Height: 64 +Passive frames: 19 +Active frames: 0 +Frames order: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 +Active cycles: 0 +Frame rate: 4 +Duration: 3600 +Active cooldown: 0 + +Bubble slots: 0 diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/SPIRAL/frame_0.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/SPIRAL/frame_0.bm new file mode 100644 index 0000000000..91f8a999cc Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/SPIRAL/frame_0.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/SPIRAL/frame_1.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/SPIRAL/frame_1.bm new file mode 100644 index 0000000000..4b87fe2900 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/SPIRAL/frame_1.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/SPIRAL/frame_10.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/SPIRAL/frame_10.bm new file mode 100644 index 0000000000..7419da504c Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/SPIRAL/frame_10.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/SPIRAL/frame_11.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/SPIRAL/frame_11.bm new file mode 100644 index 0000000000..c26e7a4016 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/SPIRAL/frame_11.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/SPIRAL/frame_12.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/SPIRAL/frame_12.bm new file mode 100644 index 0000000000..c82f73459c Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/SPIRAL/frame_12.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/SPIRAL/frame_13.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/SPIRAL/frame_13.bm new file mode 100644 index 0000000000..48b89c616c Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/SPIRAL/frame_13.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/SPIRAL/frame_14.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/SPIRAL/frame_14.bm new file mode 100644 index 0000000000..a1324f0358 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/SPIRAL/frame_14.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/SPIRAL/frame_15.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/SPIRAL/frame_15.bm new file mode 100644 index 0000000000..9eb53dc3cd Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/SPIRAL/frame_15.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/SPIRAL/frame_16.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/SPIRAL/frame_16.bm new file mode 100644 index 0000000000..75930f4127 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/SPIRAL/frame_16.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/SPIRAL/frame_17.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/SPIRAL/frame_17.bm new file mode 100644 index 0000000000..57d647faa0 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/SPIRAL/frame_17.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/SPIRAL/frame_18.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/SPIRAL/frame_18.bm new file mode 100644 index 0000000000..d28a84762e Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/SPIRAL/frame_18.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/SPIRAL/frame_19.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/SPIRAL/frame_19.bm new file mode 100644 index 0000000000..9ee10bad6a Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/SPIRAL/frame_19.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/SPIRAL/frame_2.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/SPIRAL/frame_2.bm new file mode 100644 index 0000000000..8ea8a8fd6d Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/SPIRAL/frame_2.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/SPIRAL/frame_20.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/SPIRAL/frame_20.bm new file mode 100644 index 0000000000..d5088dcb6e Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/SPIRAL/frame_20.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/SPIRAL/frame_21.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/SPIRAL/frame_21.bm new file mode 100644 index 0000000000..eae8629fdc Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/SPIRAL/frame_21.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/SPIRAL/frame_22.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/SPIRAL/frame_22.bm new file mode 100644 index 0000000000..19e553a621 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/SPIRAL/frame_22.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/SPIRAL/frame_23.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/SPIRAL/frame_23.bm new file mode 100644 index 0000000000..0626d2e985 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/SPIRAL/frame_23.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/SPIRAL/frame_3.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/SPIRAL/frame_3.bm new file mode 100644 index 0000000000..03dba1ff0b Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/SPIRAL/frame_3.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/SPIRAL/frame_4.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/SPIRAL/frame_4.bm new file mode 100644 index 0000000000..44b6efaad3 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/SPIRAL/frame_4.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/SPIRAL/frame_5.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/SPIRAL/frame_5.bm new file mode 100644 index 0000000000..0b30ad8160 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/SPIRAL/frame_5.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/SPIRAL/frame_6.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/SPIRAL/frame_6.bm new file mode 100644 index 0000000000..6d5564f7c7 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/SPIRAL/frame_6.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/SPIRAL/frame_7.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/SPIRAL/frame_7.bm new file mode 100644 index 0000000000..1837267744 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/SPIRAL/frame_7.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/SPIRAL/frame_8.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/SPIRAL/frame_8.bm new file mode 100644 index 0000000000..91f09a3c81 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/SPIRAL/frame_8.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/SPIRAL/frame_9.bm b/assets/resources/dolphin_custom/WatchDogs/Anims/SPIRAL/frame_9.bm new file mode 100644 index 0000000000..cf4ffc443a Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Anims/SPIRAL/frame_9.bm differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/SPIRAL/meta.txt b/assets/resources/dolphin_custom/WatchDogs/Anims/SPIRAL/meta.txt new file mode 100644 index 0000000000..81cc6c7d92 --- /dev/null +++ b/assets/resources/dolphin_custom/WatchDogs/Anims/SPIRAL/meta.txt @@ -0,0 +1,14 @@ +Filetype: Flipper Animation +Version: 1 + +Width: 128 +Height: 64 +Passive frames: 24 +Active frames: 0 +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 +Active cycles: 0 +Frame rate: 4 +Duration: 3600 +Active cooldown: 0 + +Bubble slots: 0 diff --git a/assets/resources/dolphin_custom/WatchDogs/Anims/manifest.txt b/assets/resources/dolphin_custom/WatchDogs/Anims/manifest.txt new file mode 100644 index 0000000000..5e82ab29c5 --- /dev/null +++ b/assets/resources/dolphin_custom/WatchDogs/Anims/manifest.txt @@ -0,0 +1,142 @@ +Filetype: Flipper Animation Manifest +Version: 1 + +Name: BOTTY_CALL +Min butthurt: 0 +Max butthurt: 18 +Min level: 1 +Max level: 30 +Weight: 3 + +Name: DEDSEC_AD +Min butthurt: 0 +Max butthurt: 18 +Min level: 1 +Max level: 30 +Weight: 3 + +Name: DEDSEC_ANIM +Min butthurt: 0 +Max butthurt: 18 +Min level: 1 +Max level: 30 +Weight: 3 + +Name: DEDSEC_ASCII +Min butthurt: 0 +Max butthurt: 18 +Min level: 1 +Max level: 30 +Weight: 3 + +Name: DEDSEC_LOGO +Min butthurt: 0 +Max butthurt: 18 +Min level: 1 +Max level: 30 +Weight: 3 + +Name: DEDSEC_OLD +Min butthurt: 0 +Max butthurt: 18 +Min level: 1 +Max level: 30 +Weight: 3 + +Name: DEDSEC_TALK +Min butthurt: 0 +Max butthurt: 18 +Min level: 1 +Max level: 30 +Weight: 3 + +Name: DEDSEC_WAVE +Min butthurt: 0 +Max butthurt: 18 +Min level: 1 +Max level: 30 +Weight: 3 + +Name: FINGER +Min butthurt: 0 +Max butthurt: 18 +Min level: 1 +Max level: 30 +Weight: 3 + +Name: GUNS_CAR +Min butthurt: 0 +Max butthurt: 18 +Min level: 1 +Max level: 30 +Weight: 3 + +Name: HANDS +Min butthurt: 0 +Max butthurt: 18 +Min level: 1 +Max level: 30 +Weight: 3 + +Name: JOIN_US +Min butthurt: 0 +Max butthurt: 18 +Min level: 1 +Max level: 30 +Weight: 3 + +Name: LOGO_WD2 +Min butthurt: 0 +Max butthurt: 18 +Min level: 1 +Max level: 30 +Weight: 3 + +Name: MARCUS +Min butthurt: 0 +Max butthurt: 18 +Min level: 1 +Max level: 30 +Weight: 3 + +Name: MUMMY +Min butthurt: 0 +Max butthurt: 18 +Min level: 1 +Max level: 30 +Weight: 3 + +Name: REAPER +Min butthurt: 0 +Max butthurt: 18 +Min level: 1 +Max level: 30 +Weight: 3 + +Name: REAPER_ALT +Min butthurt: 0 +Max butthurt: 18 +Min level: 1 +Max level: 30 +Weight: 3 + +Name: SKULL +Min butthurt: 0 +Max butthurt: 18 +Min level: 1 +Max level: 30 +Weight: 3 + +Name: SKULL_SPIN +Min butthurt: 0 +Max butthurt: 18 +Min level: 1 +Max level: 30 +Weight: 3 + +Name: SPIRAL +Min butthurt: 0 +Max butthurt: 18 +Min level: 1 +Max level: 30 +Weight: 3 diff --git a/assets/resources/dolphin_custom/WatchDogs/Icons/NFC/NFC_dolphin_emulation_47x61.bmx b/assets/resources/dolphin_custom/WatchDogs/Icons/NFC/NFC_dolphin_emulation_47x61.bmx new file mode 100644 index 0000000000..3b5661bfc5 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Icons/NFC/NFC_dolphin_emulation_47x61.bmx differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Icons/Passport/passport_bad_46x49.bmx b/assets/resources/dolphin_custom/WatchDogs/Icons/Passport/passport_bad_46x49.bmx new file mode 100644 index 0000000000..e42148b612 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Icons/Passport/passport_bad_46x49.bmx differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Icons/Passport/passport_happy_46x49.bmx b/assets/resources/dolphin_custom/WatchDogs/Icons/Passport/passport_happy_46x49.bmx new file mode 100644 index 0000000000..a445a8f7ba Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Icons/Passport/passport_happy_46x49.bmx differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Icons/Passport/passport_okay_46x49.bmx b/assets/resources/dolphin_custom/WatchDogs/Icons/Passport/passport_okay_46x49.bmx new file mode 100644 index 0000000000..9d93b8e9e7 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Icons/Passport/passport_okay_46x49.bmx differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Icons/RFID/RFIDDolphinReceive_97x61.bmx b/assets/resources/dolphin_custom/WatchDogs/Icons/RFID/RFIDDolphinReceive_97x61.bmx new file mode 100644 index 0000000000..51446057af Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Icons/RFID/RFIDDolphinReceive_97x61.bmx differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Icons/RFID/RFIDDolphinSend_97x61.bmx b/assets/resources/dolphin_custom/WatchDogs/Icons/RFID/RFIDDolphinSend_97x61.bmx new file mode 100644 index 0000000000..51446057af Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Icons/RFID/RFIDDolphinSend_97x61.bmx differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Icons/RFID/rfid_success.bmx b/assets/resources/dolphin_custom/WatchDogs/Icons/RFID/rfid_success.bmx new file mode 100644 index 0000000000..14f6efc320 Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Icons/RFID/rfid_success.bmx differ diff --git a/assets/resources/dolphin_custom/WatchDogs/Icons/SubGhz/Scanning_123x52.bmx b/assets/resources/dolphin_custom/WatchDogs/Icons/SubGhz/Scanning_123x52.bmx new file mode 100644 index 0000000000..7c576cb7bb Binary files /dev/null and b/assets/resources/dolphin_custom/WatchDogs/Icons/SubGhz/Scanning_123x52.bmx differ diff --git a/assets/resources/subghz/Stores/Lowes/Wirecutting.sub b/assets/resources/subghz/Stores/Lowes/Wirecutting.sub new file mode 100644 index 0000000000..67b863e465 --- /dev/null +++ b/assets/resources/subghz/Stores/Lowes/Wirecutting.sub @@ -0,0 +1,9 @@ +Filetype: Flipper SubGhz RAW File +Version: 1 +Frequency: 303875000 +Preset: FuriHalSubGhzPresetOok650Async +Protocol: RAW +RAW_Data: 363 -103368 99 -66 67 -198 131 -64 129 -230 167 -200 263 -102 133 -562 603 -96986 101 -236 133 -100 99 -268 131 -330 99 -300 99 -298 99 -200 333 -168 167 -18274 301 -166 167 -134 167 -268 65 -75970 65 -200 163 -66 65 -196 263 -264 99 -336 65 -266 165 -266 131 -236 135 -96968 231 -196 165 -202 563 -166 133 -200 269 -134 167 -266 165 -97100 129 -262 263 -196 99 -260 129 -66 97 -198 65 -228 97 -196 295 -230 129 -51262 601 -200 65 -234 135 -268 133 -264 99 -368 65 -302 167 -42778 165 -202 335 -198 133 -236 133 -168 169 -272 165 -168 625 -96984 291 -434 497 -230 231 -232 99 -97176 261 -194 161 -164 625 -230 65 -164 257 -196 97 -262 131 -84532 131 -226 95 -98 65 -332 97 -230 65 -196 65 -428 97 -132 131 -168 67 -270 67 -9376 529 -230 129 -520 131 -330 67 -166 133 -166 229 -97100 131 -270 133 -530 327 -66 97 -166 129 -198 65 -97224 99 -228 129 -294 97 -134 67 -168 165 -306 65 -236 299 -102 265 -97264 167 -200 199 -168 203 -238 65 -266 197 -168 301 -100 129 -366 65 -17560 99 -164 291 -166 131 -568 165 -200 99 -68 99 -234 65 -166 101 -168 165 -76538 65 -700 131 -132 591 -296 97 -97634 131 -66 65 -236 99 -300 199 -164 301 -198 135 -168 99 -334 97 -266 135 -96998 165 -236 299 -168 165 -170 165 -266 65 -266 297 -198 133 -200 133 -50496 329 -300 97 -1066 67 -232 135 -304 65 -43894 167 -366 97 -260 97 -264 159 -230 197 -198 129 -296 99 -97094 357 -364 65 -326 65 -326 327 -132 163 -97122 131 -66 133 -326 65 -264 593 -198 199 -134 299 -83502 557 -200 133 -164 919 -164 195 -228 129 -10882 599 -168 131 -398 199 -204 101 -268 327 -164 161 -97112 327 -66 63 -192 65 -162 197 -230 129 -134 97 -166 163 -266 163 -194 231 -198 97 -96812 129 -918 131 -262 459 -332 99 -232 233 -97236 589 -66 65 -166 133 -170 199 -168 301 -200 131 -196 161 -16874 133 -300 65 -700 99 -234 165 -200 525 -164 163 -77794 99 -164 229 -232 97 -358 65 -200 127 -296 65 -296 327 -166 99 -96954 135 -266 295 -166 163 -240 133 -234 133 -268 101 -232 237 -200 131 -97072 133 -100 133 -304 99 -304 101 -66 99 -234 167 -232 129 -196 359 -49548 135 -234 529 -164 165 -338 65 -168 65 -204 237 -202 197 -43548 1057 -10716 1011 -4890 1001 -2002 993 -4920 1007 -7834 975 -2004 993 -4914 1005 -7798 1003 -2004 991 -7824 1005 -4916 973 -2040 989 -4916 977 -4920 1009 -7798 997 -2006 1009 -4890 1023 -4882 1005 -4900 1011 -4900 989 -7826 987 -10746 987 -4916 +RAW_Data: 1009 -2004 977 -4922 983 -7832 1013 -2002 975 -4926 983 -7836 1013 -2002 981 -7834 1013 -4924 981 -2004 1007 -4896 1013 -4900 1025 -7824 987 -2024 1003 -4920 993 -4914 985 -4932 975 -4930 1009 -7826 987 -10742 977 -4914 1011 -2006 1001 -4926 979 -7828 985 -2014 979 -4950 979 -7828 1009 -1986 1015 -7822 989 -4942 973 -2026 979 -4902 1021 -4880 1005 -7818 1011 -1992 989 -4916 1007 -4904 1013 -4892 1009 -4882 1013 -7802 1021 -10702 983 -4938 985 -2000 1005 -4894 1011 -7802 1011 -2004 973 -4922 1015 -7804 1013 -2002 981 -7826 1013 -4914 985 -2034 971 -4940 973 -4924 1019 -7822 985 -2026 977 -4920 987 -4938 989 -4936 977 -4926 981 -7822 1007 -10728 1013 -4890 1013 -2000 985 -4926 987 -7830 973 -2024 983 -4926 1001 -7822 981 -2002 1009 -7816 1013 -4922 985 -2032 973 -4942 975 -4922 987 -7822 1021 -1986 1015 -4892 1011 -4912 987 -4918 985 -4910 1009 -7826 983 -10702 1023 -4880 1007 -2010 973 -4912 993 -7832 1009 -1974 991 -4912 1007 -7818 981 -2010 1009 -7826 987 -4928 1011 -1992 1021 -4904 997 -4920 1009 -7836 977 -2038 983 -4912 1007 -4918 1005 -4910 985 -4936 979 -7826 1021 -10724 1013 -4890 1009 -2004 1007 -4898 1011 -7802 1013 -2000 1011 -4902 1015 -7814 1019 -1966 1021 -7814 1009 -4924 983 -2034 971 -4946 1009 -4900 1001 -7820 1021 -1998 1011 -4894 1023 -4912 1001 -4908 975 -4902 1025 -7826 1003 -10686 1031 -4890 987 -2000 1009 -4894 1009 -7802 1013 -2002 975 -4930 985 -7802 1005 -2004 1015 -7800 989 -4910 1009 -2022 991 -4912 997 -4916 1009 -7834 979 -2032 997 -4912 985 -4918 1021 -4896 1013 -4908 987 -7854 987 -10728 1011 -4922 981 -2000 1007 -4900 1009 -7830 983 -1998 1031 -4890 1007 -7836 979 -2002 997 -7840 1009 -4916 1009 -1986 1011 -4922 985 -4912 1007 -7820 1011 -2028 991 -4910 997 -4910 1005 -4912 1011 -4914 981 -7832 1011 -10706 1013 -4888 1021 -1980 1007 -4914 973 -7834 985 -2030 975 -4888 1013 -7824 985 -2014 985 -7824 1011 -4914 975 -2008 1001 -4922 985 -4914 1009 -7814 985 -2008 1013 -4910 1005 -4906 1013 -4920 979 -4916 1009 -7812 1011 -10748 985 -4910 1005 -2026 977 -4922 981 -7830 987 -2018 1013 -4890 1007 -7822 1007 -2018 967 -7836 1003 -4916 1015 -1996 1005 -4920 1009 -4918 985 -7828 1011 -2004 1007 -4900 1009 -4922 985 -4912 1007 -4932 1001 -7806 993 -10740 1019 -4898 1013 -1982 1011 -4918 979 -7800 1023 -2006 975 -4924 973 -7832 971 -2026 975 -7834 985 -4912 1007 -2020 977 -4896 1029 -4880 1017 -7818 983 -2030 983 -4914 1009 -4898 981 -4916 1011 -4918 977 -7828 1013 -10752 1003 -4910 991 -2034 975 -4918 1009 -7832 985 -2010 977 -4920 1009 -7834 985 -2010 1009 -7818 987 -4924 1013 -2008 979 -4940 1003 -4914 973 -7850 997 -2000 999 -4922 1007 -4910 1005 -4930 973 -4926 987 -7856 987 -10736 1005 -4894 1005 -2006 995 -4906 1007 -7828 1009 -2010 +RAW_Data: 989 -4914 973 -7828 979 -2006 993 -7830 1007 -4926 971 -2004 993 -4914 1007 -4924 971 -7832 985 -2030 977 -4916 985 -4912 1009 -4906 1015 -4892 1007 -7824 977 -10736 981 -4944 977 -1994 999 -4920 1007 -7836 977 -2006 993 -4920 1007 -7834 977 -2002 993 -7864 975 -4916 1013 -2006 983 -4952 981 -4910 1009 -7848 975 -2014 989 -4948 973 -4932 1001 -4892 1005 -4912 1025 -7830 977 -10740 1017 -4920 989 -2006 975 -4918 1011 -7834 989 -1996 1013 -4914 977 -7844 983 -2028 981 -7846 995 -4910 977 -2038 979 -4896 1025 -4910 1007 -7798 1015 -2008 989 -4914 971 -4920 1015 -4882 997 -4908 1011 -7820 1009 -10712 985 -4908 1011 -2004 975 -4920 985 -7836 1009 -2004 977 -4922 985 -7836 1011 -2004 981 -7830 1011 -4906 1003 -2002 993 -4918 1007 -4922 1011 -7836 985 -1998 1011 -4904 1029 -4914 977 -4916 1011 -4926 989 -7834 1007 -10716 1011 -4922 987 -2008 973 -4918 1013 -7804 1019 -2002 1013 -4886 1021 -7820 985 -2026 975 -7838 989 -4948 971 -2028 975 -4924 991 -4944 999 -7830 975 -2006 989 -4942 973 -4908 1011 -4892 1013 -4912 985 -7842 987 -10710 1009 -4892 999 -2004 997 -4910 975 -7838 983 -2002 1007 -4896 983 -7828 1013 -2004 983 -7838 1013 -4900 1001 -2000 993 -4920 1007 -4920 1013 -7834 987 -2006 1011 -4916 977 -4924 1017 -4912 985 -4910 1007 -7822 1011 -10740 999 -4910 997 -2010 1009 -4918 977 -7838 983 -2032 983 -4914 1011 -7802 1011 -2014 981 -7828 1019 -4898 1015 -2014 977 -4914 1009 -4906 1007 -7832 987 -2032 999 -4918 1007 -4886 1003 -4916 995 -4920 973 -7832 1005 -10732 969 -4914 1013 -1978 1015 -4884 1017 -7802 991 -2006 1007 -4914 979 -7832 983 -1992 999 -7838 997 -4912 1001 -2002 1009 -4916 991 -4916 999 -7824 1009 -2008 995 -4910 993 -4922 1005 -4922 1007 -4916 1001 -7824 985 -173058 65 -132 99 -166 167 -266 63 -132 97 -166 201 -168 167 -68 133 -300 331 -45308 333 -100 131 -564 297 -168 431 -198 169 -236 133 -48820 99 -270 101 -302 133 -462 65 -428 99 -198 129 -232 129 -97044 559 -196 129 -198 131 -260 261 -162 455 -228 163 -97128 537 -200 265 -100 131 -532 231 -230 131 -234 67 -78622 133 -268 167 -66 99 -500 361 -162 195 -162 259 -15646 555 -328 293 -132 163 -228 95 -264 129 -264 99 -97218 161 -292 227 -166 165 -204 237 -434 99 -266 603 -97108 267 -166 131 -600 99 -234 299 -234 99 -134 269 -168 267 -97106 133 -302 65 -598 131 -300 67 -266 561 -200 167 -11630 557 -196 99 -236 561 -194 97 -262 97 -260 195 -82784 331 -166 131 -200 131 -600 563 -332 165 -97280 335 -132 165 -234 133 -202 133 -296 99 -266 101 -296 129 -360 65 -97000 229 -198 163 -196 689 -132 65 -166 235 -166 293 -198 97 -44574 331 -134 131 -266 +RAW_Data: 135 -434 65 -302 293 -262 131 -264 131 -260 99 -500 99 -336 133 -266 97 -402 133 -704 99 -41108 301 -166 229 -166 165 -266 65 -536 99 -334 231 -166 233 -97320 295 -392 97 -164 129 -194 127 -230 97 -166 65 -164 291 -77382 299 -504 99 -100 165 -434 165 -266 197 -16738 165 -636 99 -234 99 -698 99 -534 131 -97300 333 -430 97 -264 97 -392 97 -196 293 -230 63 -294 97 -97106 131 -298 65 -300 101 -568 99 -198 67 -198 131 -234 133 -268 99 -97214 131 -164 131 -66 95 -230 65 -950 131 -228 161 -10470 99 -296 295 -230 97 -198 99 -304 101 -502 365 -196 65 -83734 131 -232 99 -296 263 -166 265 -234 99 -298 67 -232 133 -66 65 -234 99 -97032 295 -234 67 -234 231 -730 133 -404 65 -143692 299 -196 97 -264 133 -234 131 -196 95 -160 63 -228 129 -228 97 -66 131 -42744 131 -326 131 -528 65 -328 97 -300 559 -232 129 -97158 131 -302 99 -596 133 -234 99 -434 99 -164 97 -196 99 diff --git a/assets/resources/subghz/playlist/Lowes_playlist.txt b/assets/resources/subghz/playlist/Lowes_playlist.txt index b0909e441e..edcaf8ef8c 100644 --- a/assets/resources/subghz/playlist/Lowes_playlist.txt +++ b/assets/resources/subghz/playlist/Lowes_playlist.txt @@ -4,4 +4,5 @@ sub: /ext/subghz/Stores/Lowes/Outdoor_Power_Equipment_Desk.sub sub: /ext/subghz/Stores/Lowes/Flooring_Desk.sub sub: /ext/subghz/Stores/Lowes/Electrical.sub sub: /ext/subghz/Stores/Lowes/Blind_Cutting.sub -sub: /ext/subghz/Stores/Lowes/Appliance_Desk.sub \ No newline at end of file +sub: /ext/subghz/Stores/Lowes/Appliance_Desk.sub +sub: /ext/subghz/Stores/Lowes/Wirecutting.sub \ No newline at end of file diff --git a/fbt_options.py b/fbt_options.py index 0458ea03bc..8fb8f1429c 100644 --- a/fbt_options.py +++ b/fbt_options.py @@ -14,7 +14,7 @@ # Suffix to add to files when building distribution # If OS environment has DIST_SUFFIX set, it will be used instead -DIST_SUFFIX = "XFW-0039_01172023" +DIST_SUFFIX = "XFW-0040_01252023" # Coprocessor firmware COPRO_OB_DATA = "scripts/ob.data" diff --git a/firmware.scons b/firmware.scons index d674bf160e..3922c136e1 100644 --- a/firmware.scons +++ b/firmware.scons @@ -15,6 +15,7 @@ env = ENV.Clone( ("compilation_db", {"COMPILATIONDB_COMSTR": "\tCDB\t${TARGET}"}), "fwbin", "fbt_apps", + "pvsstudio", ], COMPILATIONDB_USE_ABSPATH=False, BUILD_DIR=fw_build_meta["build_dir"], @@ -69,6 +70,8 @@ env = ENV.Clone( ], }, }, + SDK_APISYMS=None, + _APP_ICONS=None, ) @@ -128,9 +131,6 @@ if extra_int_apps := GetOption("extra_int_apps"): fwenv.Append(APPS=extra_int_apps.split(",")) -if fwenv["FAP_EXAMPLES"]: - fwenv.Append(APPDIRS=[("applications/examples", False)]) - for app_dir, _ in env["APPDIRS"]: app_dir_node = env.Dir("#").Dir(app_dir) @@ -273,6 +273,24 @@ Precious(fwcdb) NoClean(fwcdb) Alias(fwenv["FIRMWARE_BUILD_CFG"] + "_cdb", fwcdb) +pvscheck = fwenv.PVSCheck("pvsreport.log", fwcdb) +Depends( + pvscheck, + [ + fwenv["FW_VERSION_JSON"], + fwenv["FW_ASSETS_HEADERS"], + fwenv["SDK_APISYMS"], + fwenv["_APP_ICONS"], + ], +) +Alias(fwenv["FIRMWARE_BUILD_CFG"] + "_pvscheck", pvscheck) +AlwaysBuild(pvscheck) +Precious(pvscheck) + +pvsreport = fwenv.PVSReport(None, pvscheck, REPORT_DIR=Dir("pvsreport")) +Alias(fwenv["FIRMWARE_BUILD_CFG"] + "_pvs", pvsreport) +AlwaysBuild(pvsreport) + # If current configuration was explicitly requested, generate compilation database # and link its directory as build/latest if should_gen_cdb_and_link_dir(fwenv, BUILD_TARGETS): diff --git a/firmware/targets/furi_hal_include/furi_hal_version.h b/firmware/targets/furi_hal_include/furi_hal_version.h index 297090732c..3e524b75cd 100644 --- a/firmware/targets/furi_hal_include/furi_hal_version.h +++ b/firmware/targets/furi_hal_include/furi_hal_version.h @@ -16,8 +16,8 @@ extern "C" { #define FURI_HAL_VERSION_NAME_LENGTH 8 #define FURI_HAL_VERSION_ARRAY_NAME_LENGTH (FURI_HAL_VERSION_NAME_LENGTH + 1) -/** BLE symbol + "Flipper " + name */ -#define FURI_HAL_VERSION_DEVICE_NAME_LENGTH (1 + 8 + FURI_HAL_VERSION_ARRAY_NAME_LENGTH) +/** BLE symbol + name */ +#define FURI_HAL_VERSION_DEVICE_NAME_LENGTH (1 + FURI_HAL_VERSION_ARRAY_NAME_LENGTH) /** OTP Versions enum */ typedef enum { diff --git a/furi/core/core_defines.h b/furi/core/core_defines.h index a0f50aff96..03a364abd0 100644 --- a/furi/core/core_defines.h +++ b/furi/core/core_defines.h @@ -93,7 +93,11 @@ extern "C" { #endif #ifndef FURI_BIT_CLEAR -#define FURI_BIT_CLEAR(x, n) ((x) &= ~(1UL << (n))) +#define FURI_BIT_CLEAR(x, n) \ + ({ \ + __typeof__(x) _x = (1); \ + (x) &= ~(_x << (n)); \ + }) #endif #define FURI_SW_MEMBARRIER() asm volatile("" : : : "memory") diff --git a/lib/flipper_application/flipper_application.c b/lib/flipper_application/flipper_application.c index 618a362311..8b049a7d4f 100644 --- a/lib/flipper_application/flipper_application.c +++ b/lib/flipper_application/flipper_application.c @@ -1,5 +1,6 @@ #include "flipper_application.h" #include "elf/elf_file.h" +#include #define TAG "fapp" @@ -95,6 +96,15 @@ static int32_t flipper_application_thread(void* context) { elf_file_pre_run(last_loaded_app->elf); int32_t result = elf_file_run(last_loaded_app->elf, context); elf_file_post_run(last_loaded_app->elf); + + // wait until all notifications from RAM are completed + NotificationApp* notifications = furi_record_open(RECORD_NOTIFICATION); + const NotificationSequence sequence_empty = { + NULL, + }; + notification_message_block(notifications, &sequence_empty); + furi_record_close(RECORD_NOTIFICATION); + return result; } diff --git a/lib/lfrfid/protocols/protocol_fdx_b.c b/lib/lfrfid/protocols/protocol_fdx_b.c index 855356f2af..dd54cffb06 100644 --- a/lib/lfrfid/protocols/protocol_fdx_b.c +++ b/lib/lfrfid/protocols/protocol_fdx_b.c @@ -244,7 +244,7 @@ LevelDuration protocol_fdx_b_encoder_yield(ProtocolFDXB* protocol) { static uint64_t protocol_fdx_b_get_national_code(const uint8_t* data) { uint64_t national_code = bit_lib_get_bits_32(data, 0, 32); national_code = national_code << 32; - national_code |= bit_lib_get_bits_32(data, 32, 6) << (32 - 6); + national_code |= (uint64_t)bit_lib_get_bits_32(data, 32, 6) << (32 - 6); bit_lib_reverse_bits((uint8_t*)&national_code, 0, 64); return national_code; } diff --git a/lib/subghz/blocks/math.h b/lib/subghz/blocks/math.h index 87c209f71d..dcea3da5fa 100644 --- a/lib/subghz/blocks/math.h +++ b/lib/subghz/blocks/math.h @@ -5,8 +5,16 @@ #include #define bit_read(value, bit) (((value) >> (bit)) & 0x01) -#define bit_set(value, bit) ((value) |= (1UL << (bit))) -#define bit_clear(value, bit) ((value) &= ~(1UL << (bit))) +#define bit_set(value, bit) \ + ({ \ + __typeof__(value) _one = (1); \ + (value) |= (_one << (bit)); \ + }) +#define bit_clear(value, bit) \ + ({ \ + __typeof__(value) _one = (1); \ + (value) &= ~(_one << (bit)); \ + }) #define bit_write(value, bit, bitvalue) (bitvalue ? bit_set(value, bit) : bit_clear(value, bit)) #define DURATION_DIFF(x, y) (((x) < (y)) ? ((y) - (x)) : ((x) - (y))) diff --git a/lib/subghz/protocols/chamberlain_code.c b/lib/subghz/protocols/chamberlain_code.c index 3650a98673..32f4e9520e 100644 --- a/lib/subghz/protocols/chamberlain_code.c +++ b/lib/subghz/protocols/chamberlain_code.c @@ -280,9 +280,9 @@ static bool subghz_protocol_chamb_code_to_bit(uint64_t* data, uint8_t size) { uint64_t data_tmp = data[0]; uint64_t data_res = 0; for(uint8_t i = 0; i < size; i++) { - if((data_tmp & 0xF) == CHAMBERLAIN_CODE_BIT_0) { + if((data_tmp & 0xFll) == CHAMBERLAIN_CODE_BIT_0) { bit_write(data_res, i, 0); - } else if((data_tmp & 0xF) == CHAMBERLAIN_CODE_BIT_1) { + } else if((data_tmp & 0xFll) == CHAMBERLAIN_CODE_BIT_1) { bit_write(data_res, i, 1); } else { return false; diff --git a/lib/subghz/protocols/secplus_v1.c b/lib/subghz/protocols/secplus_v1.c index c1c0d39661..9c3afeb460 100644 --- a/lib/subghz/protocols/secplus_v1.c +++ b/lib/subghz/protocols/secplus_v1.c @@ -224,7 +224,7 @@ static bool subghz_protocol_secplus_v1_encode(SubGhzProtocolEncoderSecPlus_v1* i instance->generic.data &= 0xFFFFFFFF00000000; instance->generic.data |= rolling; - if(rolling > 0xFFFFFFFF) { + if(rolling == 0xFFFFFFFF) { rolling = 0xE6000000; } if(fixed > 0xCFD41B90) { diff --git a/scripts/asset_packer.py b/scripts/asset_packer.py new file mode 100755 index 0000000000..54c598ea52 --- /dev/null +++ b/scripts/asset_packer.py @@ -0,0 +1,111 @@ +#!/usr/bin/env python +from PIL import Image, ImageOps +import heatshrink2 +import pathlib +import shutil +import struct +import typing +import time +import io + + +def convert_bm(img: "Image.Image | pathlib.Path") -> bytes: + if not isinstance(img, Image.Image): + img = Image.open(img) + + with io.BytesIO() as output: + img = img.convert("1") + img = ImageOps.invert(img) + img.save(output, format="XBM") + xbm = output.getvalue() + + f = io.StringIO(xbm.decode().strip()) + data = f.read().strip().replace("\n", "").replace(" ", "").split("=")[1][:-1] + data_str = data[1:-1].replace(",", " ").replace("0x", "") + data_bin = bytearray.fromhex(data_str) + + data_encoded_str = heatshrink2.compress(data_bin, window_sz2=8, lookahead_sz2=4) + data_enc = bytearray(data_encoded_str) + data_enc = bytearray([len(data_enc) & 0xFF, len(data_enc) >> 8]) + data_enc + + if len(data_enc) < len(data_bin) + 1: + return b"\x01\x00" + data_enc + else: + return b"\x00" + data_bin + + +def convert_bmx(img: "Image.Image | pathlib.Path") -> bytes: + if not isinstance(img, Image.Image): + img = Image.open(img) + + data = struct.pack("