Eric Betts 8 месяцев назад
Родитель
Сommit
97791f4d39
7 измененных файлов с 418 добавлено и 24 удалено
  1. 30 0
      scenes/weebo_scene.c
  2. 29 0
      scenes/weebo_scene.h
  3. 1 0
      scenes/weebo_scene_config.h
  4. 58 0
      scenes/weebo_scene_start.c
  5. 196 24
      weebo.c
  6. 5 0
      weebo.h
  7. 99 0
      weebo_i.h

+ 30 - 0
scenes/weebo_scene.c

@@ -0,0 +1,30 @@
+#include "weebo_scene.h"
+
+// Generate scene on_enter handlers array
+#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_enter,
+void (*const weebo_on_enter_handlers[])(void*) = {
+#include "weebo_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 weebo_on_event_handlers[])(void* context, SceneManagerEvent event) = {
+#include "weebo_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 weebo_on_exit_handlers[])(void* context) = {
+#include "weebo_scene_config.h"
+};
+#undef ADD_SCENE
+
+// Initialize scene handlers configuration structure
+const SceneManagerHandlers weebo_scene_handlers = {
+    .on_enter_handlers = weebo_on_enter_handlers,
+    .on_event_handlers = weebo_on_event_handlers,
+    .on_exit_handlers = weebo_on_exit_handlers,
+    .scene_num = WeeboSceneNum,
+};

+ 29 - 0
scenes/weebo_scene.h

@@ -0,0 +1,29 @@
+#pragma once
+
+#include <gui/scene_manager.h>
+
+// Generate scene id and total number
+#define ADD_SCENE(prefix, name, id) WeeboScene##id,
+typedef enum {
+#include "weebo_scene_config.h"
+    WeeboSceneNum,
+} WeeboScene;
+#undef ADD_SCENE
+
+extern const SceneManagerHandlers weebo_scene_handlers;
+
+// Generate scene on_enter handlers declaration
+#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_enter(void*);
+#include "weebo_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 "weebo_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 "weebo_scene_config.h"
+#undef ADD_SCENE

+ 1 - 0
scenes/weebo_scene_config.h

@@ -0,0 +1 @@
+ADD_SCENE(weebo, start, Start)

+ 58 - 0
scenes/weebo_scene_start.c

@@ -0,0 +1,58 @@
+#include "../weebo_i.h"
+enum SubmenuIndex {
+    SubmenuIndexSamPresent,
+    SubmenuIndexSamMissing,
+};
+
+static void weebo_scene_start_detect_callback(void* context) {
+    Weebo* weebo = context;
+    UNUSED(weebo);
+    // view_dispatcher_send_custom_event(weebo->view_dispatcher, WeeboWorkerEventSamMissing);
+}
+
+void weebo_scene_start_submenu_callback(void* context, uint32_t index) {
+    Weebo* weebo = context;
+    view_dispatcher_send_custom_event(weebo->view_dispatcher, index);
+}
+
+void weebo_scene_start_on_enter(void* context) {
+    Weebo* weebo = context;
+
+    Popup* popup = weebo->popup;
+
+    popup_set_context(weebo->popup, weebo);
+    popup_set_callback(weebo->popup, weebo_scene_start_detect_callback);
+    popup_set_header(popup, "Detecting SAM", 58, 48, AlignCenter, AlignCenter);
+    popup_set_timeout(weebo->popup, 2500);
+    popup_enable_timeout(weebo->popup);
+
+    view_dispatcher_switch_to_view(weebo->view_dispatcher, WeeboViewPopup);
+}
+
+bool weebo_scene_start_on_event(void* context, SceneManagerEvent event) {
+    Weebo* weebo = context;
+    bool consumed = false;
+
+    if(event.type == SceneManagerEventTypeCustom) {
+        scene_manager_set_scene_state(weebo->scene_manager, WeeboSceneStart, event.event);
+        /*
+        if(event.event == WeeboWorkerEventSamPresent) {
+            scene_manager_next_scene(weebo->scene_manager, WeeboSceneSamPresent);
+            consumed = true;
+        } else if(event.event == WeeboWorkerEventSamMissing) {
+            scene_manager_next_scene(weebo->scene_manager, WeeboSceneSamMissing);
+            consumed = true;
+        } else if(event.event == WeeboWorkerEventSamWrong) {
+            scene_manager_next_scene(weebo->scene_manager, WeeboSceneSamWrong);
+            consumed = true;
+        }
+        */
+    }
+
+    return consumed;
+}
+
+void weebo_scene_start_on_exit(void* context) {
+    Weebo* weebo = context;
+    popup_reset(weebo->popup);
+}

+ 196 - 24
weebo.c

@@ -1,19 +1,9 @@
-#include <furi.h>
-
-/* generated by fbt from .png files in images folder */
-#include <weebo_icons.h>
-#include <amiibo.h>
-
-#include "m.h"
-#include "key_retail.h"
+#include "weebo_i.h"
 
 #define TAG "weebo"
 
-#define NTAG215_SIZE     540
-#define NFC3D_UID_OFFSET 0x1D4
-#define PAGE_SIZE        4
+#define WEEBO_KEY_RETAIL_FILENAME "key_retail"
 
-nfc3d_amiibo_keys amiiboKeys;
 uint8_t original[NTAG215_SIZE];
 uint8_t plain_base[NFC3D_AMIIBO_SIZE];
 uint8_t modified[NTAG215_SIZE];
@@ -25,23 +15,205 @@ void calculate_pwd(uint8_t* uid, uint8_t* pwd) {
     pwd[3] = uid[4] ^ uid[6] ^ 0x55;
 }
 
+bool weebo_custom_event_callback(void* context, uint32_t event) {
+    furi_assert(context);
+    Weebo* weebo = context;
+    return scene_manager_handle_custom_event(weebo->scene_manager, event);
+}
+
+bool weebo_back_event_callback(void* context) {
+    furi_assert(context);
+    Weebo* weebo = context;
+    return scene_manager_handle_back_event(weebo->scene_manager);
+}
+
+void weebo_tick_event_callback(void* context) {
+    furi_assert(context);
+    Weebo* weebo = context;
+    scene_manager_handle_tick_event(weebo->scene_manager);
+}
+
+Weebo* weebo_alloc() {
+    Weebo* weebo = malloc(sizeof(Weebo));
+
+    weebo->view_dispatcher = view_dispatcher_alloc();
+    weebo->scene_manager = scene_manager_alloc(&weebo_scene_handlers, weebo);
+    view_dispatcher_set_event_callback_context(weebo->view_dispatcher, weebo);
+    view_dispatcher_set_custom_event_callback(weebo->view_dispatcher, weebo_custom_event_callback);
+    view_dispatcher_set_navigation_event_callback(
+        weebo->view_dispatcher, weebo_back_event_callback);
+    view_dispatcher_set_tick_event_callback(
+        weebo->view_dispatcher, weebo_tick_event_callback, 100);
+
+    weebo->nfc = nfc_alloc();
+
+    // Nfc device
+    weebo->nfc_device = nfc_device_alloc();
+    nfc_device_set_loading_callback(weebo->nfc_device, weebo_show_loading_popup, weebo);
+
+    // Open GUI record
+    weebo->gui = furi_record_open(RECORD_GUI);
+    view_dispatcher_attach_to_gui(
+        weebo->view_dispatcher, weebo->gui, ViewDispatcherTypeFullscreen);
+
+    // Open Notification record
+    weebo->notifications = furi_record_open(RECORD_NOTIFICATION);
+
+    // Submenu
+    weebo->submenu = submenu_alloc();
+    view_dispatcher_add_view(
+        weebo->view_dispatcher, WeeboViewMenu, submenu_get_view(weebo->submenu));
+
+    // Popup
+    weebo->popup = popup_alloc();
+    view_dispatcher_add_view(weebo->view_dispatcher, WeeboViewPopup, popup_get_view(weebo->popup));
+
+    // Loading
+    weebo->loading = loading_alloc();
+    view_dispatcher_add_view(
+        weebo->view_dispatcher, WeeboViewLoading, loading_get_view(weebo->loading));
+
+    // Text Input
+    weebo->text_input = text_input_alloc();
+    view_dispatcher_add_view(
+        weebo->view_dispatcher, WeeboViewTextInput, text_input_get_view(weebo->text_input));
+
+    // Number Input
+    weebo->number_input = number_input_alloc();
+    view_dispatcher_add_view(
+        weebo->view_dispatcher, WeeboViewNumberInput, number_input_get_view(weebo->number_input));
+
+    // TextBox
+    weebo->text_box = text_box_alloc();
+    view_dispatcher_add_view(
+        weebo->view_dispatcher, WeeboViewTextBox, text_box_get_view(weebo->text_box));
+    weebo->text_box_store = furi_string_alloc();
+
+    // Custom Widget
+    weebo->widget = widget_alloc();
+    view_dispatcher_add_view(
+        weebo->view_dispatcher, WeeboViewWidget, widget_get_view(weebo->widget));
+
+    weebo->storage = furi_record_open(RECORD_STORAGE);
+    weebo->dialogs = furi_record_open(RECORD_DIALOGS);
+    weebo->load_path = furi_string_alloc();
+
+    return weebo;
+}
+
+void weebo_free(Weebo* weebo) {
+    furi_assert(weebo);
+
+    nfc_free(weebo->nfc);
+
+    // Nfc device
+    nfc_device_free(weebo->nfc_device);
+
+    // Submenu
+    view_dispatcher_remove_view(weebo->view_dispatcher, WeeboViewMenu);
+    submenu_free(weebo->submenu);
+
+    // Popup
+    view_dispatcher_remove_view(weebo->view_dispatcher, WeeboViewPopup);
+    popup_free(weebo->popup);
+
+    // Loading
+    view_dispatcher_remove_view(weebo->view_dispatcher, WeeboViewLoading);
+    loading_free(weebo->loading);
+
+    // TextInput
+    view_dispatcher_remove_view(weebo->view_dispatcher, WeeboViewTextInput);
+    text_input_free(weebo->text_input);
+
+    // NumberInput
+    view_dispatcher_remove_view(weebo->view_dispatcher, WeeboViewNumberInput);
+    number_input_free(weebo->number_input);
+
+    // TextBox
+    view_dispatcher_remove_view(weebo->view_dispatcher, WeeboViewTextBox);
+    text_box_free(weebo->text_box);
+    furi_string_free(weebo->text_box_store);
+
+    // Custom Widget
+    view_dispatcher_remove_view(weebo->view_dispatcher, WeeboViewWidget);
+    widget_free(weebo->widget);
+
+    // View Dispatcher
+    view_dispatcher_free(weebo->view_dispatcher);
+
+    // Scene Manager
+    scene_manager_free(weebo->scene_manager);
+
+    // GUI
+    furi_record_close(RECORD_GUI);
+    weebo->gui = NULL;
+
+    // Notifications
+    furi_record_close(RECORD_NOTIFICATION);
+    weebo->notifications = NULL;
+
+    furi_string_free(weebo->load_path);
+    furi_record_close(RECORD_STORAGE);
+    furi_record_close(RECORD_DIALOGS);
+
+    free(weebo);
+}
+
+void weebo_text_store_set(Weebo* weebo, const char* text, ...) {
+    va_list args;
+    va_start(args, text);
+
+    vsnprintf(weebo->text_store, sizeof(weebo->text_store), text, args);
+
+    va_end(args);
+}
+
+void weebo_text_store_clear(Weebo* weebo) {
+    memset(weebo->text_store, 0, sizeof(weebo->text_store));
+}
+
+static const NotificationSequence weebo_sequence_blink_start_blue = {
+    &message_blink_start_10,
+    &message_blink_set_color_blue,
+    &message_do_not_reset,
+    NULL,
+};
+
+static const NotificationSequence weebo_sequence_blink_stop = {
+    &message_blink_stop,
+    NULL,
+};
+
+void weebo_blink_start(Weebo* weebo) {
+    notification_message(weebo->notifications, &weebo_sequence_blink_start_blue);
+}
+
+void weebo_blink_stop(Weebo* weebo) {
+    notification_message(weebo->notifications, &weebo_sequence_blink_stop);
+}
+
+void weebo_show_loading_popup(void* context, bool show) {
+    Weebo* weebo = context;
+
+    if(show) {
+        // Raise timer priority so that animations can play
+        furi_timer_set_thread_priority(FuriTimerThreadPriorityElevated);
+        view_dispatcher_switch_to_view(weebo->view_dispatcher, WeeboViewLoading);
+    } else {
+        // Restore default timer priority
+        furi_timer_set_thread_priority(FuriTimerThreadPriorityNormal);
+    }
+}
+
 int32_t weebo_app(void* p) {
     UNUSED(p);
-    FURI_LOG_I(TAG, "Hello world");
-    FURI_LOG_I(TAG, "I'm weebo!");
+    Weebo* weebo = weebo_alloc();
 
-    // key_retail.bin
-    memcpy(&amiiboKeys, key_retail_bin, sizeof(key_retail_bin));
+    scene_manager_next_scene(weebo->scene_manager, WeeboSceneStart);
 
-    memcpy(original, m_bin, m_bin_len);
-    memset(plain_base, 0, sizeof(plain_base));
-    memset(modified, 0, sizeof(modified));
+    view_dispatcher_run(weebo->view_dispatcher);
 
-    if(!nfc3d_amiibo_unpack(&amiiboKeys, original, plain_base)) {
-        FURI_LOG_E(TAG, "Failed to unpack amiibo keys");
-        return -1;
-    }
-    FURI_LOG_I(TAG, "Unpacked amiibo keys");
+    weebo_free(weebo);
 
     return 0;
 }

+ 5 - 0
weebo.h

@@ -0,0 +1,5 @@
+#pragma once
+
+typedef struct Weebo Weebo;
+
+bool weebo_load_key_retail(Weebo* weebo);

+ 99 - 0
weebo_i.h

@@ -0,0 +1,99 @@
+#pragma once
+
+#include <furi.h>
+#include <furi_hal.h>
+#include <gui/gui.h>
+#include <gui/view_dispatcher.h>
+#include <gui/scene_manager.h>
+#include <notification/notification_messages.h>
+#include <storage/storage.h>
+#include <dialogs/dialogs.h>
+
+#include <gui/modules/submenu.h>
+#include <gui/modules/popup.h>
+#include <gui/modules/loading.h>
+#include <gui/modules/text_input.h>
+#include <gui/modules/number_input.h>
+#include <gui/modules/text_box.h>
+#include <gui/modules/widget.h>
+
+#include <input/input.h>
+#include <lib/flipper_format/flipper_format.h>
+
+#include <lib/nfc/nfc.h>
+#include <nfc/nfc_poller.h>
+#include <nfc/nfc_device.h>
+
+/* generated by fbt from .png files in images folder */
+#include <weebo_icons.h>
+
+#include <amiibo.h>
+
+#include "weebo.h"
+#include "scenes/weebo_scene.h"
+
+#define WEEBO_TEXT_STORE_SIZE      128
+#define WEEBO_FILE_NAME_MAX_LENGTH 64
+
+#define NTAG215_SIZE     540
+#define NFC3D_UID_OFFSET 0x1D4
+#define PAGE_SIZE        4
+
+enum WeeboCustomEvent {
+    // Reserve first 100 events for button types and indexes, starting from 0
+    WeeboCustomEventReserved = 100,
+
+    WeeboCustomEventViewExit,
+    WeeboCustomEventTextInputDone,
+    WeeboCustomEventNumberInputDone,
+};
+
+struct Weebo {
+    ViewDispatcher* view_dispatcher;
+    Gui* gui;
+    NotificationApp* notifications;
+    SceneManager* scene_manager;
+    Storage* storage;
+
+    char text_store[WEEBO_TEXT_STORE_SIZE + 1];
+    FuriString* text_box_store;
+
+    // Common Views
+    Submenu* submenu;
+    Popup* popup;
+    Loading* loading;
+    TextInput* text_input;
+    NumberInput* number_input;
+    TextBox* text_box;
+    Widget* widget;
+    DialogsApp* dialogs;
+
+    Nfc* nfc;
+    NfcPoller* poller;
+    NfcDevice* nfc_device;
+
+    FuriString* load_path;
+    char file_name[WEEBO_FILE_NAME_MAX_LENGTH + 1];
+
+    nfc3d_amiibo_keys amiiboKeys;
+};
+
+typedef enum {
+    WeeboViewMenu,
+    WeeboViewPopup,
+    WeeboViewLoading,
+    WeeboViewTextInput,
+    WeeboViewNumberInput,
+    WeeboViewTextBox,
+    WeeboViewWidget,
+} WeeboView;
+
+void weebo_text_store_set(Weebo* weebo, const char* text, ...);
+
+void weebo_text_store_clear(Weebo* weebo);
+
+void weebo_blink_start(Weebo* weebo);
+
+void weebo_blink_stop(Weebo* weebo);
+
+void weebo_show_loading_popup(void* context, bool show);