Просмотр исходного кода

Merge pull request #15 from CodyTolene/ct/updates

Clean up/bug fixes
Cody Tolene 2 лет назад
Родитель
Сommit
1ac9afbf89

+ 190 - 0
.clang-format

@@ -0,0 +1,190 @@
+---
+Language:        Cpp
+AccessModifierOffset: -4
+AlignAfterOpenBracket: AlwaysBreak
+AlignArrayOfStructures: None
+AlignConsecutiveMacros: None
+AlignConsecutiveAssignments: None
+AlignConsecutiveBitFields: None
+AlignConsecutiveDeclarations: None
+AlignEscapedNewlines: Left
+AlignOperands:   Align
+AlignTrailingComments: false
+AllowAllArgumentsOnNextLine: true
+AllowAllParametersOfDeclarationOnNextLine: false
+AllowShortEnumsOnASingleLine: true
+AllowShortBlocksOnASingleLine: Never
+AllowShortCaseLabelsOnASingleLine: false
+AllowShortFunctionsOnASingleLine: None
+AllowShortLambdasOnASingleLine: All
+AllowShortIfStatementsOnASingleLine: WithoutElse
+AllowShortLoopsOnASingleLine: true
+AlwaysBreakAfterDefinitionReturnType: None
+AlwaysBreakAfterReturnType: None
+AlwaysBreakBeforeMultilineStrings: false
+AlwaysBreakTemplateDeclarations: Yes
+AttributeMacros:
+  - __capability
+BinPackArguments: false
+BinPackParameters: false
+BraceWrapping:
+  AfterCaseLabel:  false
+  AfterClass:      false
+  AfterControlStatement: Never
+  AfterEnum:       false
+  AfterFunction:   false
+  AfterNamespace:  false
+  AfterObjCDeclaration: false
+  AfterStruct:     false
+  AfterUnion:      false
+  AfterExternBlock: false
+  BeforeCatch:     false
+  BeforeElse:      false
+  BeforeLambdaBody: false
+  BeforeWhile:     false
+  IndentBraces:    false
+  SplitEmptyFunction: true
+  SplitEmptyRecord: true
+  SplitEmptyNamespace: true
+BreakBeforeBinaryOperators: None
+BreakBeforeConceptDeclarations: true
+BreakBeforeBraces: Attach
+BreakBeforeInheritanceComma: false
+BreakInheritanceList: BeforeColon
+BreakBeforeTernaryOperators: false
+BreakConstructorInitializersBeforeComma: false
+BreakConstructorInitializers: BeforeComma
+BreakAfterJavaFieldAnnotations: false
+BreakStringLiterals: false
+ColumnLimit:     99
+CommentPragmas:  '^ IWYU pragma:'
+QualifierAlignment: Leave
+CompactNamespaces: false
+ConstructorInitializerIndentWidth: 4
+ContinuationIndentWidth: 4
+Cpp11BracedListStyle: true
+DeriveLineEnding: true
+DerivePointerAlignment: false
+DisableFormat:   false
+EmptyLineAfterAccessModifier: Never
+EmptyLineBeforeAccessModifier: LogicalBlock
+ExperimentalAutoDetectBinPacking: false
+PackConstructorInitializers: BinPack
+BasedOnStyle:    ''
+ConstructorInitializerAllOnOneLineOrOnePerLine: false
+AllowAllConstructorInitializersOnNextLine: true
+FixNamespaceComments: false
+ForEachMacros:
+  - foreach
+  - Q_FOREACH
+  - BOOST_FOREACH
+IfMacros:
+  - KJ_IF_MAYBE
+IncludeBlocks:   Preserve
+IncludeCategories:
+  - Regex:           '.*'
+    Priority:        1
+    SortPriority:    0
+    CaseSensitive:   false
+  - Regex:           '^(<|"(gtest|gmock|isl|json)/)'
+    Priority:        3
+    SortPriority:    0
+    CaseSensitive:   false
+  - Regex:           '.*'
+    Priority:        1
+    SortPriority:    0
+    CaseSensitive:   false
+IncludeIsMainRegex: '(Test)?$'
+IncludeIsMainSourceRegex: ''
+IndentAccessModifiers: false
+IndentCaseLabels: false
+IndentCaseBlocks: false
+IndentGotoLabels: true
+IndentPPDirectives: None
+IndentExternBlock: AfterExternBlock
+IndentRequires:  false
+IndentWidth:     4
+IndentWrappedFunctionNames: true
+InsertTrailingCommas: None
+JavaScriptQuotes: Leave
+JavaScriptWrapImports: true
+KeepEmptyLinesAtTheStartOfBlocks: false
+LambdaBodyIndentation: Signature
+MacroBlockBegin: ''
+MacroBlockEnd:   ''
+MaxEmptyLinesToKeep: 1
+NamespaceIndentation: None
+ObjCBinPackProtocolList: Auto
+ObjCBlockIndentWidth: 4
+ObjCBreakBeforeNestedBlockParam: true
+ObjCSpaceAfterProperty: true
+ObjCSpaceBeforeProtocolList: true
+PenaltyBreakAssignment: 10
+PenaltyBreakBeforeFirstCallParameter: 30
+PenaltyBreakComment: 10
+PenaltyBreakFirstLessLess: 0
+PenaltyBreakOpenParenthesis: 0
+PenaltyBreakString: 10
+PenaltyBreakTemplateDeclaration: 10
+PenaltyExcessCharacter: 100
+PenaltyReturnTypeOnItsOwnLine: 60
+PenaltyIndentedWhitespace: 0
+PointerAlignment: Left
+PPIndentWidth:   -1
+ReferenceAlignment: Pointer
+ReflowComments:  false
+RemoveBracesLLVM: false
+SeparateDefinitionBlocks: Leave
+ShortNamespaceLines: 1
+SortIncludes:    Never
+SortJavaStaticImport: Before
+SortUsingDeclarations: false
+SpaceAfterCStyleCast: false
+SpaceAfterLogicalNot: false
+SpaceAfterTemplateKeyword: true
+SpaceBeforeAssignmentOperators: true
+SpaceBeforeCaseColon: false
+SpaceBeforeCpp11BracedList: false
+SpaceBeforeCtorInitializerColon: true
+SpaceBeforeInheritanceColon: true
+SpaceBeforeParens: Never
+SpaceBeforeParensOptions:
+  AfterControlStatements: false
+  AfterForeachMacros: false
+  AfterFunctionDefinitionName: false
+  AfterFunctionDeclarationName: false
+  AfterIfMacros:   false
+  AfterOverloadedOperator: false
+  BeforeNonEmptyParentheses: false
+SpaceAroundPointerQualifiers: Default
+SpaceBeforeRangeBasedForLoopColon: true
+SpaceInEmptyBlock: false
+SpaceInEmptyParentheses: false
+SpacesBeforeTrailingComments: 1
+SpacesInAngles:  Never
+SpacesInConditionalStatement: false
+SpacesInContainerLiterals: false
+SpacesInCStyleCastParentheses: false
+SpacesInLineCommentPrefix:
+  Minimum:         1
+  Maximum:         -1
+SpacesInParentheses: false
+SpacesInSquareBrackets: false
+SpaceBeforeSquareBrackets: false
+BitFieldColonSpacing: Both
+Standard:        c++03
+StatementAttributeLikeMacros:
+  - Q_EMIT
+StatementMacros:
+  - Q_UNUSED
+  - QT_REQUIRE_VERSION
+TabWidth:        4
+UseCRLF:         false
+UseTab:          Never
+WhitespaceSensitiveMacros:
+  - STRINGIZE
+  - PP_STRINGIZE
+  - BOOST_PP_STRINGIZE
+  - NS_SWIFT_NAME
+  - CF_SWIFT_NAME
+...

+ 36 - 0
.github/workflows/deploy-main.yml

@@ -0,0 +1,36 @@
+name: "Build + upload."
+on:
+    push:
+      branches:
+          # Run on push to main.
+        - main
+    schedule:
+        # Run every day at 00:00 UTC (midnight)
+      - cron: "0 0 * * *"
+jobs:
+  ufbt-build-action:
+    runs-on: ubuntu-latest
+    strategy:
+      matrix:
+        include:
+          - name: dev channel
+            sdk-channel: dev
+          - name: release channel
+            sdk-channel: release
+    name: 'ufbt: Build for ${{ matrix.name }}'
+    steps:
+      - name: Checkout
+        uses: actions/checkout@v3
+        with:
+          submodules: recursive
+      - name: Build with ufbt
+        uses: flipperdevices/flipperzero-ufbt-action@v0.1.2
+        id: build-app
+        with:
+          app-dir: ./src-fap
+          sdk-channel: ${{ matrix.sdk-channel }}
+      - name: Upload app artifacts
+        uses: actions/upload-artifact@v3
+        with:
+          name: ${{ github.event.repository.name }}-${{ steps.build-app.outputs.suffix }}
+          path: ${{ steps.build-app.outputs.fap-artifacts }}

+ 22 - 0
.github/workflows/lint-pull-request.yml

@@ -0,0 +1,22 @@
+name: "Build test + lint."
+on: pull_request
+jobs:
+  ufbt-build-action:
+    runs-on: ubuntu-latest
+    name: 'ufbt: Build for Dev branch'
+    steps:
+      - name: Checkout
+        uses: actions/checkout@v3
+      - name: Build with ufbt
+        # Flipper Zero ufbt action
+        # https://github.com/flipperdevices/flipperzero-ufbt-action
+        uses: flipperdevices/flipperzero-ufbt-action@v0.1.2
+        id: build-app
+        with:
+          app-dir: ./src-fap
+          sdk-channel: dev
+      - name: Lint sources
+        uses: flipperdevices/flipperzero-ufbt-action@v0.1.2
+        with:
+          skip-setup: true
+          task: lint

+ 9 - 16
src-fap/camera_suite.c

@@ -13,7 +13,7 @@ void camera_suite_tick_event_callback(void* context) {
     scene_manager_handle_tick_event(app->scene_manager);
     scene_manager_handle_tick_event(app->scene_manager);
 }
 }
 
 
-//leave app if back button pressed
+// Leave app if back button pressed.
 bool camera_suite_navigation_event_callback(void* context) {
 bool camera_suite_navigation_event_callback(void* context) {
     furi_assert(context);
     furi_assert(context);
     CameraSuite* app = context;
     CameraSuite* app = context;
@@ -25,10 +25,10 @@ CameraSuite* camera_suite_app_alloc() {
     app->gui = furi_record_open(RECORD_GUI);
     app->gui = furi_record_open(RECORD_GUI);
     app->notification = furi_record_open(RECORD_NOTIFICATION);
     app->notification = furi_record_open(RECORD_NOTIFICATION);
 
 
-    //Turn backlight on, believe me this makes testing your app easier
+    // Turn backlight on.
     notification_message(app->notification, &sequence_display_backlight_on);
     notification_message(app->notification, &sequence_display_backlight_on);
 
 
-    //Scene additions
+    // Scene additions
     app->view_dispatcher = view_dispatcher_alloc();
     app->view_dispatcher = view_dispatcher_alloc();
     view_dispatcher_enable_queue(app->view_dispatcher);
     view_dispatcher_enable_queue(app->view_dispatcher);
 
 
@@ -60,17 +60,11 @@ CameraSuite* camera_suite_app_alloc() {
         CameraSuiteViewIdStartscreen,
         CameraSuiteViewIdStartscreen,
         camera_suite_view_start_get_view(app->camera_suite_view_start));
         camera_suite_view_start_get_view(app->camera_suite_view_start));
 
 
-    app->camera_suite_view_style_1 = camera_suite_view_style_1_alloc();
+    app->camera_suite_view_camera = camera_suite_view_camera_alloc();
     view_dispatcher_add_view(
     view_dispatcher_add_view(
         app->view_dispatcher,
         app->view_dispatcher,
-        CameraSuiteViewIdScene1,
-        camera_suite_view_style_1_get_view(app->camera_suite_view_style_1));
-
-    app->camera_suite_view_style_2 = camera_suite_view_style_2_alloc();
-    view_dispatcher_add_view(
-        app->view_dispatcher,
-        CameraSuiteViewIdScene2,
-        camera_suite_view_style_2_get_view(app->camera_suite_view_style_2));
+        CameraSuiteViewIdCamera,
+        camera_suite_view_camera_get_view(app->camera_suite_view_camera));
 
 
     app->camera_suite_view_guide = camera_suite_view_guide_alloc();
     app->camera_suite_view_guide = camera_suite_view_guide_alloc();
     view_dispatcher_add_view(
     view_dispatcher_add_view(
@@ -98,9 +92,9 @@ void camera_suite_app_free(CameraSuite* app) {
     scene_manager_free(app->scene_manager);
     scene_manager_free(app->scene_manager);
 
 
     // View Dispatcher
     // View Dispatcher
+    view_dispatcher_remove_view(app->view_dispatcher, CameraSuiteViewIdStartscreen);
     view_dispatcher_remove_view(app->view_dispatcher, CameraSuiteViewIdMenu);
     view_dispatcher_remove_view(app->view_dispatcher, CameraSuiteViewIdMenu);
-    view_dispatcher_remove_view(app->view_dispatcher, CameraSuiteViewIdScene1);
-    view_dispatcher_remove_view(app->view_dispatcher, CameraSuiteViewIdScene2);
+    view_dispatcher_remove_view(app->view_dispatcher, CameraSuiteViewIdCamera);
     view_dispatcher_remove_view(app->view_dispatcher, CameraSuiteViewIdGuide);
     view_dispatcher_remove_view(app->view_dispatcher, CameraSuiteViewIdGuide);
     view_dispatcher_remove_view(app->view_dispatcher, CameraSuiteViewIdSettings);
     view_dispatcher_remove_view(app->view_dispatcher, CameraSuiteViewIdSettings);
     submenu_free(app->submenu);
     submenu_free(app->submenu);
@@ -110,8 +104,7 @@ void camera_suite_app_free(CameraSuite* app) {
 
 
     // Free remaining resources
     // Free remaining resources
     camera_suite_view_start_free(app->camera_suite_view_start);
     camera_suite_view_start_free(app->camera_suite_view_start);
-    camera_suite_view_style_1_free(app->camera_suite_view_style_1);
-    camera_suite_view_style_2_free(app->camera_suite_view_style_2);
+    camera_suite_view_camera_free(app->camera_suite_view_camera);
     camera_suite_view_guide_free(app->camera_suite_view_guide);
     camera_suite_view_guide_free(app->camera_suite_view_guide);
     button_menu_free(app->button_menu);
     button_menu_free(app->button_menu);
     variable_item_list_free(app->variable_item_list);
     variable_item_list_free(app->variable_item_list);

+ 3 - 7
src-fap/camera_suite.h

@@ -4,9 +4,7 @@
 #include "scenes/camera_suite_scene.h"
 #include "scenes/camera_suite_scene.h"
 #include "views/camera_suite_view_guide.h"
 #include "views/camera_suite_view_guide.h"
 #include "views/camera_suite_view_start.h"
 #include "views/camera_suite_view_start.h"
-#include "views/camera_suite_view_style_1.h"
-#include "views/camera_suite_view_style_2.h"
-#include <assets_icons.h>
+#include "views/camera_suite_view_camera.h"
 #include <furi.h>
 #include <furi.h>
 #include <furi_hal.h>
 #include <furi_hal.h>
 #include <gui/gui.h>
 #include <gui/gui.h>
@@ -29,8 +27,7 @@ typedef struct {
     SceneManager* scene_manager;
     SceneManager* scene_manager;
     VariableItemList* variable_item_list;
     VariableItemList* variable_item_list;
     CameraSuiteViewStart* camera_suite_view_start;
     CameraSuiteViewStart* camera_suite_view_start;
-    CameraSuiteViewStyle1* camera_suite_view_style_1;
-    CameraSuiteViewStyle2* camera_suite_view_style_2;
+    CameraSuiteViewCamera* camera_suite_view_camera;
     CameraSuiteViewGuide* camera_suite_view_guide;
     CameraSuiteViewGuide* camera_suite_view_guide;
     uint32_t orientation;
     uint32_t orientation;
     uint32_t haptic;
     uint32_t haptic;
@@ -42,8 +39,7 @@ typedef struct {
 typedef enum {
 typedef enum {
     CameraSuiteViewIdStartscreen,
     CameraSuiteViewIdStartscreen,
     CameraSuiteViewIdMenu,
     CameraSuiteViewIdMenu,
-    CameraSuiteViewIdScene1,
-    CameraSuiteViewIdScene2,
+    CameraSuiteViewIdCamera,
     CameraSuiteViewIdGuide,
     CameraSuiteViewIdGuide,
     CameraSuiteViewIdSettings,
     CameraSuiteViewIdSettings,
 } CameraSuiteViewId;
 } CameraSuiteViewId;

+ 7 - 14
src-fap/helpers/camera_suite_custom_event.h

@@ -8,20 +8,13 @@ typedef enum {
     CameraSuiteCustomEventStartRight,
     CameraSuiteCustomEventStartRight,
     CameraSuiteCustomEventStartOk,
     CameraSuiteCustomEventStartOk,
     CameraSuiteCustomEventStartBack,
     CameraSuiteCustomEventStartBack,
-    // Scene events: Camera style 1
-    CameraSuiteCustomEventSceneStyle1Up,
-    CameraSuiteCustomEventSceneStyle1Down,
-    CameraSuiteCustomEventSceneStyle1Left,
-    CameraSuiteCustomEventSceneStyle1Right,
-    CameraSuiteCustomEventSceneStyle1Ok,
-    CameraSuiteCustomEventSceneStyle1Back,
-    // Scene events: Camera style 2
-    CameraSuiteCustomEventSceneStyle2Up,
-    CameraSuiteCustomEventSceneStyle2Down,
-    CameraSuiteCustomEventSceneStyle2Left,
-    CameraSuiteCustomEventSceneStyle2Right,
-    CameraSuiteCustomEventSceneStyle2Ok,
-    CameraSuiteCustomEventSceneStyle2Back,
+    // Scene events: Camera
+    CameraSuiteCustomEventSceneCameraUp,
+    CameraSuiteCustomEventSceneCameraDown,
+    CameraSuiteCustomEventSceneCameraLeft,
+    CameraSuiteCustomEventSceneCameraRight,
+    CameraSuiteCustomEventSceneCameraOk,
+    CameraSuiteCustomEventSceneCameraBack,
     // Scene events: Guide
     // Scene events: Guide
     CameraSuiteCustomEventSceneGuideUp,
     CameraSuiteCustomEventSceneGuideUp,
     CameraSuiteCustomEventSceneGuideDown,
     CameraSuiteCustomEventSceneGuideDown,

+ 14 - 14
src-fap/scenes/camera_suite_scene_style_1.c → src-fap/scenes/camera_suite_scene_camera.c

@@ -1,35 +1,35 @@
 #include "../camera_suite.h"
 #include "../camera_suite.h"
 #include "../helpers/camera_suite_custom_event.h"
 #include "../helpers/camera_suite_custom_event.h"
-#include "../views/camera_suite_view_style_1.h"
+#include "../views/camera_suite_view_camera.h"
 
 
-static void camera_suite_view_style_1_callback(CameraSuiteCustomEvent event, void* context) {
+void camera_suite_view_camera_callback(CameraSuiteCustomEvent event, void* context) {
     furi_assert(context);
     furi_assert(context);
     CameraSuite* app = context;
     CameraSuite* app = context;
     view_dispatcher_send_custom_event(app->view_dispatcher, event);
     view_dispatcher_send_custom_event(app->view_dispatcher, event);
 }
 }
 
 
-void camera_suite_scene_style_1_on_enter(void* context) {
+void camera_suite_scene_camera_on_enter(void* context) {
     furi_assert(context);
     furi_assert(context);
     CameraSuite* app = context;
     CameraSuite* app = context;
-    camera_suite_view_style_1_set_callback(
-        app->camera_suite_view_style_1, camera_suite_view_style_1_callback, app);
-    view_dispatcher_switch_to_view(app->view_dispatcher, CameraSuiteViewIdScene1);
+    camera_suite_view_camera_set_callback(
+        app->camera_suite_view_camera, camera_suite_view_camera_callback, app);
+    view_dispatcher_switch_to_view(app->view_dispatcher, CameraSuiteViewIdCamera);
 }
 }
 
 
-bool camera_suite_scene_style_1_on_event(void* context, SceneManagerEvent event) {
+bool camera_suite_scene_camera_on_event(void* context, SceneManagerEvent event) {
     CameraSuite* app = context;
     CameraSuite* app = context;
     bool consumed = false;
     bool consumed = false;
 
 
     if(event.type == SceneManagerEventTypeCustom) {
     if(event.type == SceneManagerEventTypeCustom) {
         switch(event.event) {
         switch(event.event) {
-        case CameraSuiteCustomEventSceneStyle1Left:
-        case CameraSuiteCustomEventSceneStyle1Right:
-        case CameraSuiteCustomEventSceneStyle1Up:
-        case CameraSuiteCustomEventSceneStyle1Down:
-        case CameraSuiteCustomEventSceneStyle1Ok:
+        case CameraSuiteCustomEventSceneCameraLeft:
+        case CameraSuiteCustomEventSceneCameraRight:
+        case CameraSuiteCustomEventSceneCameraUp:
+        case CameraSuiteCustomEventSceneCameraDown:
+        case CameraSuiteCustomEventSceneCameraOk:
             // Do nothing.
             // Do nothing.
             break;
             break;
-        case CameraSuiteCustomEventSceneStyle1Back:
+        case CameraSuiteCustomEventSceneCameraBack:
             notification_message(app->notification, &sequence_reset_red);
             notification_message(app->notification, &sequence_reset_red);
             notification_message(app->notification, &sequence_reset_green);
             notification_message(app->notification, &sequence_reset_green);
             notification_message(app->notification, &sequence_reset_blue);
             notification_message(app->notification, &sequence_reset_blue);
@@ -46,7 +46,7 @@ bool camera_suite_scene_style_1_on_event(void* context, SceneManagerEvent event)
     return consumed;
     return consumed;
 }
 }
 
 
-void camera_suite_scene_style_1_on_exit(void* context) {
+void camera_suite_scene_camera_on_exit(void* context) {
     CameraSuite* app = context;
     CameraSuite* app = context;
     UNUSED(app);
     UNUSED(app);
 }
 }

+ 1 - 2
src-fap/scenes/camera_suite_scene_config.h

@@ -1,6 +1,5 @@
 ADD_SCENE(camera_suite, start, Start)
 ADD_SCENE(camera_suite, start, Start)
 ADD_SCENE(camera_suite, menu, Menu)
 ADD_SCENE(camera_suite, menu, Menu)
-ADD_SCENE(camera_suite, style_1, Style_1)
-ADD_SCENE(camera_suite, style_2, Style_2)
+ADD_SCENE(camera_suite, camera, Camera)
 ADD_SCENE(camera_suite, guide, Guide)
 ADD_SCENE(camera_suite, guide, Guide)
 ADD_SCENE(camera_suite, settings, Settings)
 ADD_SCENE(camera_suite, settings, Settings)

+ 6 - 20
src-fap/scenes/camera_suite_scene_menu.c

@@ -1,10 +1,8 @@
 #include "../camera_suite.h"
 #include "../camera_suite.h"
 
 
 enum SubmenuIndex {
 enum SubmenuIndex {
-    /** Atkinson Dithering Algorithm. */
-    SubmenuIndexSceneStyle1 = 10,
-    /** Floyd-Steinberg Dithering Algorithm. */
-    SubmenuIndexSceneStyle2,
+    /** Camera. */
+    SubmenuIndexSceneCamera = 10,
     /** Guide/how-to. */
     /** Guide/how-to. */
     SubmenuIndexGuide,
     SubmenuIndexGuide,
     /** Settings menu. */
     /** Settings menu. */
@@ -22,16 +20,9 @@ void camera_suite_scene_menu_on_enter(void* context) {
     submenu_add_item(
     submenu_add_item(
         app->submenu,
         app->submenu,
         "Open Camera",
         "Open Camera",
-        SubmenuIndexSceneStyle1,
+        SubmenuIndexSceneCamera,
         camera_suite_scene_menu_submenu_callback,
         camera_suite_scene_menu_submenu_callback,
         app);
         app);
-    // Staged view for the future.
-    // submenu_add_item(
-    //     app->submenu,
-    //     "Test",
-    //     SubmenuIndexSceneStyle2,
-    //     camera_suite_scene_menu_submenu_callback,
-    //     app);
     submenu_add_item(
     submenu_add_item(
         app->submenu, "Guide", SubmenuIndexGuide, camera_suite_scene_menu_submenu_callback, app);
         app->submenu, "Guide", SubmenuIndexGuide, camera_suite_scene_menu_submenu_callback, app);
     submenu_add_item(
     submenu_add_item(
@@ -56,15 +47,10 @@ bool camera_suite_scene_menu_on_event(void* context, SceneManagerEvent event) {
         view_dispatcher_stop(app->view_dispatcher);
         view_dispatcher_stop(app->view_dispatcher);
         return true;
         return true;
     } else if(event.type == SceneManagerEventTypeCustom) {
     } else if(event.type == SceneManagerEventTypeCustom) {
-        if(event.event == SubmenuIndexSceneStyle1) {
+        if(event.event == SubmenuIndexSceneCamera) {
             scene_manager_set_scene_state(
             scene_manager_set_scene_state(
-                app->scene_manager, CameraSuiteSceneMenu, SubmenuIndexSceneStyle1);
-            scene_manager_next_scene(app->scene_manager, CameraSuiteSceneStyle_1);
-            return true;
-        } else if(event.event == SubmenuIndexSceneStyle2) {
-            scene_manager_set_scene_state(
-                app->scene_manager, CameraSuiteSceneMenu, SubmenuIndexSceneStyle2);
-            scene_manager_next_scene(app->scene_manager, CameraSuiteSceneStyle_2);
+                app->scene_manager, CameraSuiteSceneMenu, SubmenuIndexSceneCamera);
+            scene_manager_next_scene(app->scene_manager, CameraSuiteSceneCamera);
             return true;
             return true;
         } else if(event.event == SubmenuIndexGuide) {
         } else if(event.event == SubmenuIndexGuide) {
             scene_manager_set_scene_state(
             scene_manager_set_scene_state(

+ 1 - 1
src-fap/scenes/camera_suite_scene_start.c

@@ -24,9 +24,9 @@ bool camera_suite_scene_start_on_event(void* context, SceneManagerEvent event) {
         switch(event.event) {
         switch(event.event) {
         case CameraSuiteCustomEventStartLeft:
         case CameraSuiteCustomEventStartLeft:
         case CameraSuiteCustomEventStartRight:
         case CameraSuiteCustomEventStartRight:
-            break;
         case CameraSuiteCustomEventStartUp:
         case CameraSuiteCustomEventStartUp:
         case CameraSuiteCustomEventStartDown:
         case CameraSuiteCustomEventStartDown:
+            // Do nothing.
             break;
             break;
         case CameraSuiteCustomEventStartOk:
         case CameraSuiteCustomEventStartOk:
             scene_manager_next_scene(app->scene_manager, CameraSuiteSceneMenu);
             scene_manager_next_scene(app->scene_manager, CameraSuiteSceneMenu);

+ 0 - 54
src-fap/scenes/camera_suite_scene_style_2.c

@@ -1,54 +0,0 @@
-#include "../camera_suite.h"
-#include "../helpers/camera_suite_custom_event.h"
-#include "../helpers/camera_suite_haptic.h"
-#include "../helpers/camera_suite_led.h"
-#include "../views/camera_suite_view_style_2.h"
-
-void camera_suite_view_style_2_callback(CameraSuiteCustomEvent event, void* context) {
-    furi_assert(context);
-    CameraSuite* app = context;
-    view_dispatcher_send_custom_event(app->view_dispatcher, event);
-}
-
-void camera_suite_scene_style_2_on_enter(void* context) {
-    furi_assert(context);
-    CameraSuite* app = context;
-    camera_suite_view_style_2_set_callback(
-        app->camera_suite_view_style_2, camera_suite_view_style_2_callback, app);
-    view_dispatcher_switch_to_view(app->view_dispatcher, CameraSuiteViewIdScene2);
-}
-
-bool camera_suite_scene_style_2_on_event(void* context, SceneManagerEvent event) {
-    CameraSuite* app = context;
-    bool consumed = false;
-
-    if(event.type == SceneManagerEventTypeCustom) {
-        switch(event.event) {
-        case CameraSuiteCustomEventSceneStyle2Left:
-        case CameraSuiteCustomEventSceneStyle2Right:
-        case CameraSuiteCustomEventSceneStyle2Up:
-        case CameraSuiteCustomEventSceneStyle2Down:
-        case CameraSuiteCustomEventSceneStyle2Ok:
-            // Do nothing.
-            break;
-        case CameraSuiteCustomEventSceneStyle2Back:
-            notification_message(app->notification, &sequence_reset_red);
-            notification_message(app->notification, &sequence_reset_green);
-            notification_message(app->notification, &sequence_reset_blue);
-            if(!scene_manager_search_and_switch_to_previous_scene(
-                   app->scene_manager, CameraSuiteSceneMenu)) {
-                scene_manager_stop(app->scene_manager);
-                view_dispatcher_stop(app->view_dispatcher);
-            }
-            consumed = true;
-            break;
-        }
-    }
-
-    return consumed;
-}
-
-void camera_suite_scene_style_2_on_exit(void* context) {
-    CameraSuite* app = context;
-    UNUSED(app);
-}

+ 41 - 47
src-fap/views/camera_suite_view_style_1.c → src-fap/views/camera_suite_view_camera.c

@@ -8,23 +8,19 @@
 #include "../helpers/camera_suite_speaker.h"
 #include "../helpers/camera_suite_speaker.h"
 #include "../helpers/camera_suite_led.h"
 #include "../helpers/camera_suite_led.h"
 
 
-static CameraSuiteViewStyle1* current_instance = NULL;
-// Dithering type:
-//    0 = Floyd Steinberg (default)
-//    1 = Atkinson
-static int current_dithering = 0;
-
-struct CameraSuiteViewStyle1 {
-    CameraSuiteViewStyle1Callback callback;
+static CameraSuiteViewCamera* current_instance = NULL;
+
+struct CameraSuiteViewCamera {
+    CameraSuiteViewCameraCallback callback;
     FuriStreamBuffer* rx_stream;
     FuriStreamBuffer* rx_stream;
     FuriThread* worker_thread;
     FuriThread* worker_thread;
     View* view;
     View* view;
     void* context;
     void* context;
 };
 };
 
 
-void camera_suite_view_style_1_set_callback(
-    CameraSuiteViewStyle1* instance,
-    CameraSuiteViewStyle1Callback callback,
+void camera_suite_view_camera_set_callback(
+    CameraSuiteViewCamera* instance,
+    CameraSuiteViewCameraCallback callback,
     void* context) {
     void* context) {
     furi_assert(instance);
     furi_assert(instance);
     furi_assert(callback);
     furi_assert(callback);
@@ -32,7 +28,7 @@ void camera_suite_view_style_1_set_callback(
     instance->context = context;
     instance->context = context;
 }
 }
 
 
-static void camera_suite_view_style_1_draw(Canvas* canvas, UartDumpModel* model) {
+static void camera_suite_view_camera_draw(Canvas* canvas, UartDumpModel* model) {
     // Clear the screen.
     // Clear the screen.
     canvas_set_color(canvas, ColorBlack);
     canvas_set_color(canvas, ColorBlack);
 
 
@@ -69,7 +65,7 @@ static void camera_suite_view_style_1_draw(Canvas* canvas, UartDumpModel* model)
         }
         }
 
 
         for(uint8_t i = 0; i < 8; ++i) {
         for(uint8_t i = 0; i < 8; ++i) {
-            if((model->pixels[p] & (1 << i)) != 0) {
+            if((model->pixels[p] & (1 << (7 - i))) != 0) {
                 // Adjust the coordinates based on the new screen dimensions
                 // Adjust the coordinates based on the new screen dimensions
                 uint16_t screen_x, screen_y;
                 uint16_t screen_x, screen_y;
                 switch(app->orientation) {
                 switch(app->orientation) {
@@ -107,15 +103,15 @@ static void camera_suite_view_style_1_draw(Canvas* canvas, UartDumpModel* model)
     }
     }
 }
 }
 
 
-static void camera_suite_view_style_1_model_init(UartDumpModel* const model) {
+static void camera_suite_view_camera_model_init(UartDumpModel* const model) {
     for(size_t i = 0; i < FRAME_BUFFER_LENGTH; i++) {
     for(size_t i = 0; i < FRAME_BUFFER_LENGTH; i++) {
         model->pixels[i] = 0;
         model->pixels[i] = 0;
     }
     }
 }
 }
 
 
-static bool camera_suite_view_style_1_input(InputEvent* event, void* context) {
+static bool camera_suite_view_camera_input(InputEvent* event, void* context) {
     furi_assert(context);
     furi_assert(context);
-    CameraSuiteViewStyle1* instance = context;
+    CameraSuiteViewCamera* instance = context;
     if(event->type == InputTypeRelease) {
     if(event->type == InputTypeRelease) {
         switch(event->key) {
         switch(event->key) {
         default: // Stop all sounds, reset the LED.
         default: // Stop all sounds, reset the LED.
@@ -144,7 +140,7 @@ static bool camera_suite_view_style_1_input(InputEvent* event, void* context) {
                 UartDumpModel * model,
                 UartDumpModel * model,
                 {
                 {
                     UNUSED(model);
                     UNUSED(model);
-                    instance->callback(CameraSuiteCustomEventSceneStyle1Back, instance->context);
+                    instance->callback(CameraSuiteCustomEventSceneCameraBack, instance->context);
                 },
                 },
                 true);
                 true);
             break;
             break;
@@ -159,7 +155,7 @@ static bool camera_suite_view_style_1_input(InputEvent* event, void* context) {
                     camera_suite_play_happy_bump(instance->context);
                     camera_suite_play_happy_bump(instance->context);
                     camera_suite_play_input_sound(instance->context);
                     camera_suite_play_input_sound(instance->context);
                     camera_suite_led_set_rgb(instance->context, 0, 0, 255);
                     camera_suite_led_set_rgb(instance->context, 0, 0, 255);
-                    instance->callback(CameraSuiteCustomEventSceneStyle1Left, instance->context);
+                    instance->callback(CameraSuiteCustomEventSceneCameraLeft, instance->context);
                 },
                 },
                 true);
                 true);
             break;
             break;
@@ -174,7 +170,7 @@ static bool camera_suite_view_style_1_input(InputEvent* event, void* context) {
                     camera_suite_play_happy_bump(instance->context);
                     camera_suite_play_happy_bump(instance->context);
                     camera_suite_play_input_sound(instance->context);
                     camera_suite_play_input_sound(instance->context);
                     camera_suite_led_set_rgb(instance->context, 0, 0, 255);
                     camera_suite_led_set_rgb(instance->context, 0, 0, 255);
-                    instance->callback(CameraSuiteCustomEventSceneStyle1Right, instance->context);
+                    instance->callback(CameraSuiteCustomEventSceneCameraRight, instance->context);
                 },
                 },
                 true);
                 true);
             break;
             break;
@@ -189,7 +185,7 @@ static bool camera_suite_view_style_1_input(InputEvent* event, void* context) {
                     camera_suite_play_happy_bump(instance->context);
                     camera_suite_play_happy_bump(instance->context);
                     camera_suite_play_input_sound(instance->context);
                     camera_suite_play_input_sound(instance->context);
                     camera_suite_led_set_rgb(instance->context, 0, 0, 255);
                     camera_suite_led_set_rgb(instance->context, 0, 0, 255);
-                    instance->callback(CameraSuiteCustomEventSceneStyle1Up, instance->context);
+                    instance->callback(CameraSuiteCustomEventSceneCameraUp, instance->context);
                 },
                 },
                 true);
                 true);
             break;
             break;
@@ -204,18 +200,13 @@ static bool camera_suite_view_style_1_input(InputEvent* event, void* context) {
                     camera_suite_play_happy_bump(instance->context);
                     camera_suite_play_happy_bump(instance->context);
                     camera_suite_play_input_sound(instance->context);
                     camera_suite_play_input_sound(instance->context);
                     camera_suite_led_set_rgb(instance->context, 0, 0, 255);
                     camera_suite_led_set_rgb(instance->context, 0, 0, 255);
-                    instance->callback(CameraSuiteCustomEventSceneStyle1Down, instance->context);
+                    instance->callback(CameraSuiteCustomEventSceneCameraDown, instance->context);
                 },
                 },
                 true);
                 true);
             break;
             break;
         case InputKeyOk:
         case InputKeyOk:
-            if(current_dithering == 0) {
-                data[0] = 'd'; // Update to Floyd Steinberg dithering.
-                current_dithering = 1;
-            } else {
-                data[0] = 'D'; // Update to Atkinson dithering.
-                current_dithering = 0;
-            }
+            // Switch dithering types.
+            data[0] = 'D';
             with_view_model(
             with_view_model(
                 instance->view,
                 instance->view,
                 UartDumpModel * model,
                 UartDumpModel * model,
@@ -224,7 +215,7 @@ static bool camera_suite_view_style_1_input(InputEvent* event, void* context) {
                     camera_suite_play_happy_bump(instance->context);
                     camera_suite_play_happy_bump(instance->context);
                     camera_suite_play_input_sound(instance->context);
                     camera_suite_play_input_sound(instance->context);
                     camera_suite_led_set_rgb(instance->context, 0, 0, 255);
                     camera_suite_led_set_rgb(instance->context, 0, 0, 255);
-                    instance->callback(CameraSuiteCustomEventSceneStyle1Ok, instance->context);
+                    instance->callback(CameraSuiteCustomEventSceneCameraOk, instance->context);
                 },
                 },
                 true);
                 true);
             break;
             break;
@@ -237,16 +228,16 @@ static bool camera_suite_view_style_1_input(InputEvent* event, void* context) {
     return true;
     return true;
 }
 }
 
 
-static void camera_suite_view_style_1_exit(void* context) {
+static void camera_suite_view_camera_exit(void* context) {
     furi_assert(context);
     furi_assert(context);
 }
 }
 
 
-static void camera_suite_view_style_1_enter(void* context) {
+static void camera_suite_view_camera_enter(void* context) {
     // Check `context` for null. If it is null, abort program, else continue.
     // Check `context` for null. If it is null, abort program, else continue.
     furi_assert(context);
     furi_assert(context);
 
 
-    // Cast `context` to `CameraSuiteViewStyle1*` and store it in `instance`.
-    CameraSuiteViewStyle1* instance = (CameraSuiteViewStyle1*)context;
+    // Cast `context` to `CameraSuiteViewCamera*` and store it in `instance`.
+    CameraSuiteViewCamera* instance = (CameraSuiteViewCamera*)context;
 
 
     // Assign the current instance to the global variable
     // Assign the current instance to the global variable
     current_instance = instance;
     current_instance = instance;
@@ -259,7 +250,7 @@ static void camera_suite_view_style_1_enter(void* context) {
     with_view_model(
     with_view_model(
         instance->view,
         instance->view,
         UartDumpModel * model,
         UartDumpModel * model,
-        { camera_suite_view_style_1_model_init(model); },
+        { camera_suite_view_camera_model_init(model); },
         true);
         true);
 }
 }
 
 
@@ -267,8 +258,8 @@ static void camera_on_irq_cb(UartIrqEvent uartIrqEvent, uint8_t data, void* cont
     // Check `context` for null. If it is null, abort program, else continue.
     // Check `context` for null. If it is null, abort program, else continue.
     furi_assert(context);
     furi_assert(context);
 
 
-    // Cast `context` to `CameraSuiteViewStyle1*` and store it in `instance`.
-    CameraSuiteViewStyle1* instance = context;
+    // Cast `context` to `CameraSuiteViewCamera*` and store it in `instance`.
+    CameraSuiteViewCamera* instance = context;
 
 
     // If `uartIrqEvent` is `UartIrqEventRXNE`, send the data to the
     // If `uartIrqEvent` is `UartIrqEventRXNE`, send the data to the
     // `rx_stream` and set the `WorkerEventRx` flag.
     // `rx_stream` and set the `WorkerEventRx` flag.
@@ -319,7 +310,7 @@ static void process_ringbuffer(UartDumpModel* model, uint8_t byte) {
 
 
 static int32_t camera_worker(void* context) {
 static int32_t camera_worker(void* context) {
     furi_assert(context);
     furi_assert(context);
-    CameraSuiteViewStyle1* instance = context;
+    CameraSuiteViewCamera* instance = context;
 
 
     while(1) {
     while(1) {
         uint32_t events =
         uint32_t events =
@@ -348,14 +339,17 @@ static int32_t camera_worker(void* context) {
                         false);
                         false);
                 }
                 }
             } while(length > 0);
             } while(length > 0);
+
+            with_view_model(
+                instance->view, UartDumpModel * model, { UNUSED(model); }, true);
         }
         }
     }
     }
 
 
     return 0;
     return 0;
 }
 }
 
 
-CameraSuiteViewStyle1* camera_suite_view_style_1_alloc() {
-    CameraSuiteViewStyle1* instance = malloc(sizeof(CameraSuiteViewStyle1));
+CameraSuiteViewCamera* camera_suite_view_camera_alloc() {
+    CameraSuiteViewCamera* instance = malloc(sizeof(CameraSuiteViewCamera));
 
 
     instance->view = view_alloc();
     instance->view = view_alloc();
 
 
@@ -364,15 +358,15 @@ CameraSuiteViewStyle1* camera_suite_view_style_1_alloc() {
     // Set up views
     // Set up views
     view_allocate_model(instance->view, ViewModelTypeLocking, sizeof(UartDumpModel));
     view_allocate_model(instance->view, ViewModelTypeLocking, sizeof(UartDumpModel));
     view_set_context(instance->view, instance); // furi_assert crashes in events without this
     view_set_context(instance->view, instance); // furi_assert crashes in events without this
-    view_set_draw_callback(instance->view, (ViewDrawCallback)camera_suite_view_style_1_draw);
-    view_set_input_callback(instance->view, camera_suite_view_style_1_input);
-    view_set_enter_callback(instance->view, camera_suite_view_style_1_enter);
-    view_set_exit_callback(instance->view, camera_suite_view_style_1_exit);
+    view_set_draw_callback(instance->view, (ViewDrawCallback)camera_suite_view_camera_draw);
+    view_set_input_callback(instance->view, camera_suite_view_camera_input);
+    view_set_enter_callback(instance->view, camera_suite_view_camera_enter);
+    view_set_exit_callback(instance->view, camera_suite_view_camera_exit);
 
 
     with_view_model(
     with_view_model(
         instance->view,
         instance->view,
         UartDumpModel * model,
         UartDumpModel * model,
-        { camera_suite_view_style_1_model_init(model); },
+        { camera_suite_view_camera_model_init(model); },
         true);
         true);
 
 
     instance->worker_thread = furi_thread_alloc_ex("UsbUartWorker", 2048, camera_worker, instance);
     instance->worker_thread = furi_thread_alloc_ex("UsbUartWorker", 2048, camera_worker, instance);
@@ -386,7 +380,7 @@ CameraSuiteViewStyle1* camera_suite_view_style_1_alloc() {
     return instance;
     return instance;
 }
 }
 
 
-void camera_suite_view_style_1_free(CameraSuiteViewStyle1* instance) {
+void camera_suite_view_camera_free(CameraSuiteViewCamera* instance) {
     furi_assert(instance);
     furi_assert(instance);
 
 
     with_view_model(
     with_view_model(
@@ -395,7 +389,7 @@ void camera_suite_view_style_1_free(CameraSuiteViewStyle1* instance) {
     free(instance);
     free(instance);
 }
 }
 
 
-View* camera_suite_view_style_1_get_view(CameraSuiteViewStyle1* instance) {
+View* camera_suite_view_camera_get_view(CameraSuiteViewCamera* instance) {
     furi_assert(instance);
     furi_assert(instance);
     return instance->view;
     return instance->view;
-}
+}

+ 15 - 14
src-fap/views/camera_suite_view_style_1.h → src-fap/views/camera_suite_view_camera.h

@@ -16,14 +16,15 @@
 
 
 #pragma once
 #pragma once
 
 
-#define FRAME_WIDTH 128
+#define FRAME_WIDTH 129
 #define FRAME_HEIGHT 64
 #define FRAME_HEIGHT 64
 #define FRAME_BIT_DEPTH 1
 #define FRAME_BIT_DEPTH 1
-#define FRAME_BUFFER_LENGTH \
-    (FRAME_WIDTH * FRAME_HEIGHT * FRAME_BIT_DEPTH / 8) // 128*64*1 / 8 = 1024
-#define ROW_BUFFER_LENGTH (FRAME_WIDTH / 8) // 128/8 = 16
-#define RING_BUFFER_LENGTH (ROW_BUFFER_LENGTH + 3) // ROW_BUFFER_LENGTH + Header => 16 + 3 = 19
-#define LAST_ROW_INDEX (FRAME_BUFFER_LENGTH - ROW_BUFFER_LENGTH) // 1024 - 16 = 1008
+#define FRAME_BUFFER_LENGTH 1024
+#define ROW_BUFFER_LENGTH 16
+#define RING_BUFFER_LENGTH 19
+#define LAST_ROW_INDEX 1008
+
+extern const Icon I_DolphinCommon_56x48;
 
 
 typedef struct UartDumpModel UartDumpModel;
 typedef struct UartDumpModel UartDumpModel;
 
 
@@ -35,20 +36,20 @@ struct UartDumpModel {
     uint8_t row_ringbuffer[RING_BUFFER_LENGTH];
     uint8_t row_ringbuffer[RING_BUFFER_LENGTH];
 };
 };
 
 
-typedef struct CameraSuiteViewStyle1 CameraSuiteViewStyle1;
+typedef struct CameraSuiteViewCamera CameraSuiteViewCamera;
 
 
-typedef void (*CameraSuiteViewStyle1Callback)(CameraSuiteCustomEvent event, void* context);
+typedef void (*CameraSuiteViewCameraCallback)(CameraSuiteCustomEvent event, void* context);
 
 
-void camera_suite_view_style_1_set_callback(
-    CameraSuiteViewStyle1* camera_suite_view_style_1,
-    CameraSuiteViewStyle1Callback callback,
+void camera_suite_view_camera_set_callback(
+    CameraSuiteViewCamera* camera_suite_view_camera,
+    CameraSuiteViewCameraCallback callback,
     void* context);
     void* context);
 
 
-CameraSuiteViewStyle1* camera_suite_view_style_1_alloc();
+CameraSuiteViewCamera* camera_suite_view_camera_alloc();
 
 
-void camera_suite_view_style_1_free(CameraSuiteViewStyle1* camera_suite_static);
+void camera_suite_view_camera_free(CameraSuiteViewCamera* camera_suite_static);
 
 
-View* camera_suite_view_style_1_get_view(CameraSuiteViewStyle1* camera_suite_static);
+View* camera_suite_view_camera_get_view(CameraSuiteViewCamera* camera_suite_static);
 
 
 typedef enum {
 typedef enum {
     // Reserved for StreamBuffer internal event
     // Reserved for StreamBuffer internal event

+ 0 - 249
src-fap/views/camera_suite_view_style_2.c

@@ -1,249 +0,0 @@
-#include "../camera_suite.h"
-#include <furi.h>
-#include <furi_hal.h>
-#include <input/input.h>
-#include <gui/elements.h>
-#include <dolphin/dolphin.h>
-#include "../helpers/camera_suite_haptic.h"
-#include "../helpers/camera_suite_speaker.h"
-#include "../helpers/camera_suite_led.h"
-
-struct CameraSuiteViewStyle2 {
-    View* view;
-    CameraSuiteViewStyle2Callback callback;
-    void* context;
-};
-
-typedef struct {
-    int screen_text;
-} CameraSuiteViewStyle2Model;
-
-char buttonText[11][14] = {
-    "",
-    "Press Up",
-    "Press Down",
-    "Press Left",
-    "Press Right",
-    "Press Ok",
-    "Release Up",
-    "Release Down",
-    "Release Left",
-    "Release Right",
-    "Release Ok",
-};
-
-void camera_suite_view_style_2_set_callback(
-    CameraSuiteViewStyle2* instance,
-    CameraSuiteViewStyle2Callback callback,
-    void* context) {
-    furi_assert(instance);
-    furi_assert(callback);
-    instance->callback = callback;
-    instance->context = context;
-}
-
-void camera_suite_view_style_2_draw(Canvas* canvas, CameraSuiteViewStyle2Model* model) {
-    canvas_clear(canvas);
-    canvas_set_color(canvas, ColorBlack);
-    canvas_set_font(canvas, FontPrimary);
-    canvas_draw_str_aligned(canvas, 0, 10, AlignLeft, AlignTop, "Scene 2: Input Examples");
-    canvas_set_font(canvas, FontSecondary);
-    char* strInput = malloc(15);
-    strcpy(strInput, buttonText[model->screen_text]);
-    canvas_draw_str_aligned(canvas, 0, 22, AlignLeft, AlignTop, strInput);
-    free(strInput);
-}
-
-static void camera_suite_view_style_2_model_init(CameraSuiteViewStyle2Model* const model) {
-    model->screen_text = 0;
-}
-
-bool camera_suite_view_style_2_input(InputEvent* event, void* context) {
-    furi_assert(context);
-    CameraSuiteViewStyle2* instance = context;
-    if(event->type == InputTypeRelease) {
-        switch(event->key) {
-        case InputKeyBack:
-            with_view_model(
-                instance->view,
-                CameraSuiteViewStyle2Model * model,
-                {
-                    UNUSED(model);
-                    camera_suite_stop_all_sound(instance->context);
-                    instance->callback(CameraSuiteCustomEventSceneStyle2Back, instance->context);
-                    camera_suite_play_long_bump(instance->context);
-                },
-                true);
-            break;
-        case InputKeyUp:
-            with_view_model(
-                instance->view,
-                CameraSuiteViewStyle2Model * model,
-                {
-                    model->screen_text = 6;
-                    camera_suite_play_bad_bump(instance->context);
-                    camera_suite_stop_all_sound(instance->context);
-                    camera_suite_led_set_rgb(instance->context, 255, 0, 255);
-                },
-                true);
-            break;
-        case InputKeyDown:
-            with_view_model(
-                instance->view,
-                CameraSuiteViewStyle2Model * model,
-                {
-                    model->screen_text = 7;
-                    camera_suite_play_bad_bump(instance->context);
-                    camera_suite_stop_all_sound(instance->context);
-                    camera_suite_led_set_rgb(instance->context, 255, 255, 0);
-                },
-                true);
-            break;
-        case InputKeyLeft:
-            with_view_model(
-                instance->view,
-                CameraSuiteViewStyle2Model * model,
-                {
-                    model->screen_text = 8;
-                    camera_suite_play_bad_bump(instance->context);
-                    camera_suite_stop_all_sound(instance->context);
-                    camera_suite_led_set_rgb(instance->context, 0, 255, 255);
-                },
-                true);
-            break;
-        case InputKeyRight:
-            with_view_model(
-                instance->view,
-                CameraSuiteViewStyle2Model * model,
-                {
-                    model->screen_text = 9;
-                    camera_suite_play_bad_bump(instance->context);
-                    camera_suite_stop_all_sound(instance->context);
-                    camera_suite_led_set_rgb(instance->context, 255, 0, 0);
-                },
-                true);
-            break;
-        case InputKeyOk:
-            with_view_model(
-                instance->view,
-                CameraSuiteViewStyle2Model * model,
-                {
-                    model->screen_text = 10;
-                    camera_suite_play_bad_bump(instance->context);
-                    camera_suite_stop_all_sound(instance->context);
-                    camera_suite_led_set_rgb(instance->context, 255, 255, 255);
-                },
-                true);
-            break;
-        case InputKeyMAX:
-            break;
-        }
-    } else if(event->type == InputTypePress) {
-        switch(event->key) {
-        case InputKeyUp:
-            with_view_model(
-                instance->view,
-                CameraSuiteViewStyle2Model * model,
-                {
-                    model->screen_text = 1;
-                    camera_suite_play_happy_bump(instance->context);
-                    camera_suite_play_input_sound(instance->context);
-                },
-                true);
-            break;
-        case InputKeyDown:
-            with_view_model(
-                instance->view,
-                CameraSuiteViewStyle2Model * model,
-                {
-                    model->screen_text = 2;
-                    camera_suite_play_happy_bump(instance->context);
-                    camera_suite_play_input_sound(instance->context);
-                },
-                true);
-            break;
-        case InputKeyLeft:
-            with_view_model(
-                instance->view,
-                CameraSuiteViewStyle2Model * model,
-                {
-                    model->screen_text = 3;
-                    camera_suite_play_happy_bump(instance->context);
-                    camera_suite_play_input_sound(instance->context);
-                },
-                true);
-            break;
-        case InputKeyRight:
-            with_view_model(
-                instance->view,
-                CameraSuiteViewStyle2Model * model,
-                {
-                    model->screen_text = 4;
-                    camera_suite_play_happy_bump(instance->context);
-                    camera_suite_play_input_sound(instance->context);
-                },
-                true);
-            break;
-        case InputKeyOk:
-            with_view_model(
-                instance->view,
-                CameraSuiteViewStyle2Model * model,
-                {
-                    model->screen_text = 5;
-                    camera_suite_play_happy_bump(instance->context);
-                    camera_suite_play_input_sound(instance->context);
-                },
-                true);
-            break;
-        case InputKeyBack:
-        case InputKeyMAX:
-            break;
-        }
-    }
-
-    return true;
-}
-
-void camera_suite_view_style_2_exit(void* context) {
-    furi_assert(context);
-    CameraSuite* app = context;
-    camera_suite_stop_all_sound(app);
-    //camera_suite_led_reset(app);
-}
-
-void camera_suite_view_style_2_enter(void* context) {
-    furi_assert(context);
-    dolphin_deed(DolphinDeedPluginStart);
-}
-
-CameraSuiteViewStyle2* camera_suite_view_style_2_alloc() {
-    CameraSuiteViewStyle2* instance = malloc(sizeof(CameraSuiteViewStyle2));
-    instance->view = view_alloc();
-    view_allocate_model(instance->view, ViewModelTypeLocking, sizeof(CameraSuiteViewStyle2Model));
-    view_set_context(instance->view, instance);
-    view_set_draw_callback(instance->view, (ViewDrawCallback)camera_suite_view_style_2_draw);
-    view_set_input_callback(instance->view, camera_suite_view_style_2_input);
-    //view_set_enter_callback(instance->view, camera_suite_view_style_2_enter);
-    view_set_exit_callback(instance->view, camera_suite_view_style_2_exit);
-
-    with_view_model(
-        instance->view,
-        CameraSuiteViewStyle2Model * model,
-        { camera_suite_view_style_2_model_init(model); },
-        true);
-
-    return instance;
-}
-
-void camera_suite_view_style_2_free(CameraSuiteViewStyle2* instance) {
-    furi_assert(instance);
-
-    view_free(instance->view);
-    free(instance);
-}
-
-View* camera_suite_view_style_2_get_view(CameraSuiteViewStyle2* instance) {
-    furi_assert(instance);
-
-    return instance->view;
-}

+ 0 - 19
src-fap/views/camera_suite_view_style_2.h

@@ -1,19 +0,0 @@
-#pragma once
-
-#include <gui/view.h>
-#include "../helpers/camera_suite_custom_event.h"
-
-typedef struct CameraSuiteViewStyle2 CameraSuiteViewStyle2;
-
-typedef void (*CameraSuiteViewStyle2Callback)(CameraSuiteCustomEvent event, void* context);
-
-void camera_suite_view_style_2_set_callback(
-    CameraSuiteViewStyle2* instance,
-    CameraSuiteViewStyle2Callback callback,
-    void* context);
-
-CameraSuiteViewStyle2* camera_suite_view_style_2_alloc();
-
-void camera_suite_view_style_2_free(CameraSuiteViewStyle2* camera_suite_static);
-
-View* camera_suite_view_style_2_get_view(CameraSuiteViewStyle2* boilerpate_static);

+ 80 - 86
src-firmware/esp32_cam_uart_stream/esp32_cam_uart_stream.ino

@@ -26,19 +26,24 @@ camera_config_t config;
 void handleSerialInput();
 void handleSerialInput();
 void initializeCamera();
 void initializeCamera();
 void processImage(camera_fb_t* fb);
 void processImage(camera_fb_t* fb);
-void ditherImage(camera_fb_t* fb, int dt);
+void ditherImage(camera_fb_t* fb);
 bool isDarkBit(uint8_t bit);
 bool isDarkBit(uint8_t bit);
 
 
+// Dithering algorithm options
+enum DitheringAlgorithm {
+  FLOYD_STEINBERG,
+  JARVIS_JUDICE_NINKE,
+  STUCKI
+};
+
+// Default dithering algorithm
+DitheringAlgorithm ditherAlgorithm = FLOYD_STEINBERG;
+
 // Serial input flags
 // Serial input flags
 bool disableDithering = false;
 bool disableDithering = false;
 bool invert = false;
 bool invert = false;
 bool rotated = false;
 bool rotated = false;
 bool stopStream = false;
 bool stopStream = false;
-// Dithering type:
-//    0 = Floyd Steinberg (default)
-//    1 = Atkinson
-int dtType = 0;
-
 
 
 void setup() {
 void setup() {
   Serial.begin(230400);
   Serial.begin(230400);
@@ -46,24 +51,17 @@ void setup() {
 }
 }
 
 
 void loop() {
 void loop() {
-  handleSerialInput();
-
-  if (stopStream) {
-    return;
-  }
-
-  // Frame buffer.
-  camera_fb_t* fb = esp_camera_fb_get();
-
-  if (!fb) {
-    return;
+  if (!stopStream) {
+    // Frame buffer capture and processing
+    camera_fb_t* fb = esp_camera_fb_get();
+    if (fb) {
+      processImage(fb);
+      esp_camera_fb_return(fb);
+    }
+    delay(50);
   }
   }
 
 
-  processImage(fb);
-
-  esp_camera_fb_return(fb);
-  fb = NULL;
-  delay(50);
+  handleSerialInput(); // Process serial input commands
 }
 }
 
 
 void handleSerialInput() {
 void handleSerialInput() {
@@ -72,40 +70,37 @@ void handleSerialInput() {
     sensor_t* cameraSensor = esp_camera_sensor_get();
     sensor_t* cameraSensor = esp_camera_sensor_get();
 
 
     switch (input) {
     switch (input) {
-      case '>': // Toggle dithering.
+      case '>': // Toggle dithering
         disableDithering = !disableDithering;
         disableDithering = !disableDithering;
         break;
         break;
-      case '<': // Toggle invert.
+      case '<': // Toggle invert
         invert = !invert;
         invert = !invert;
         break;
         break;
-      case 'B': // Add brightness.
+      case 'B': // Add brightness
         cameraSensor->set_contrast(cameraSensor, cameraSensor->status.brightness + 1);
         cameraSensor->set_contrast(cameraSensor, cameraSensor->status.brightness + 1);
         break;
         break;
-      case 'b': // Remove brightness.
+      case 'b': // Remove brightness
         cameraSensor->set_contrast(cameraSensor, cameraSensor->status.brightness - 1);
         cameraSensor->set_contrast(cameraSensor, cameraSensor->status.brightness - 1);
         break;
         break;
-      case 'C': // Add contrast.
+      case 'C': // Add contrast
         cameraSensor->set_contrast(cameraSensor, cameraSensor->status.contrast + 1);
         cameraSensor->set_contrast(cameraSensor, cameraSensor->status.contrast + 1);
         break;
         break;
-      case 'c': // Remove contrast.
+      case 'c': // Remove contrast
         cameraSensor->set_contrast(cameraSensor, cameraSensor->status.contrast - 1);
         cameraSensor->set_contrast(cameraSensor, cameraSensor->status.contrast - 1);
         break;
         break;
-      case 'D': // Use Floyd Steinberg dithering.
-        dtType = 0;
-        break;
-      case 'd': // Use Atkinson dithering.
-        dtType = 1;
+      case 'P': // TODO: Take a picture
         break;
         break;
       case 'M': // Toggle Mirror
       case 'M': // Toggle Mirror
         cameraSensor->set_hmirror(cameraSensor, !cameraSensor->status.hmirror);
         cameraSensor->set_hmirror(cameraSensor, !cameraSensor->status.hmirror);
         break;
         break;
-      case 'S': // Start stream.
+      case 'S': // Start stream
         stopStream = false;
         stopStream = false;
         break;
         break;
-      case 's': // Stop stream.
+      case 's': // Stop stream
         stopStream = true;
         stopStream = true;
         break;
         break;
-      default:
+      case 'D': // Change dithering algorithm.
+        ditherAlgorithm = static_cast<DitheringAlgorithm>((ditherAlgorithm + 1) % 3);
         break;
         break;
     }
     }
   }
   }
@@ -147,14 +142,14 @@ void initializeCamera() {
   sensor_t* s = esp_camera_sensor_get();
   sensor_t* s = esp_camera_sensor_get();
   s->set_contrast(s, 2);
   s->set_contrast(s, 2);
 
 
-  // Set rotation (added lines)
+  // Set rotation
   s->set_vflip(s, true);  // Vertical flip
   s->set_vflip(s, true);  // Vertical flip
   s->set_hmirror(s, true);  // Horizontal mirror
   s->set_hmirror(s, true);  // Horizontal mirror
 }
 }
 
 
 void processImage(camera_fb_t* frameBuffer) {
 void processImage(camera_fb_t* frameBuffer) {
   if (!disableDithering) {
   if (!disableDithering) {
-    ditherImage(frameBuffer, dtType);
+    ditherImage(frameBuffer);
   }
   }
 
 
   uint8_t flipper_y = 0;
   uint8_t flipper_y = 0;
@@ -190,56 +185,55 @@ void processImage(camera_fb_t* frameBuffer) {
   }
   }
 }
 }
 
 
-// Dither image.
-// @param fb Frame buffer
-// @param dt Dithering type:
-//    0 = Floyd Steinberg (default)
-//    1 = Atkinson
-void ditherImage(camera_fb_t* fb, int dt) {
-  switch (dt) {
-    default:
-    case 0: // Floyd Steinberg dithering
-      for (int y = 0; y < fb->height - 1; ++y) {
-        for (int x = 1; x < fb->width - 1; ++x) {
-          int current = y * fb->width + x;
-          // Convert to black or white
-          uint8_t oldpixel = fb->buf[current];
-          uint8_t newpixel = oldpixel >= 128 ? 255 : 0;
-          fb->buf[current] = newpixel;
-          // Compute quantization error
-          int quant_error = oldpixel - newpixel;
-          // Propagate the error
-          fb->buf[current + 1] += quant_error * 7 / 16;
+void ditherImage(camera_fb_t* fb) {
+  for (uint8_t y = 0; y < fb->height; ++y) {
+    for (uint8_t x = 0; x < fb->width; ++x) {
+      size_t current = (y * fb->width) + x;
+      uint8_t oldpixel = fb->buf[current];
+      uint8_t newpixel = oldpixel >= 128 ? 255 : 0;
+      fb->buf[current] = newpixel;
+      int8_t quant_error = oldpixel - newpixel;
+
+      // Apply error diffusion based on the selected algorithm
+      switch (ditherAlgorithm) {
+        case JARVIS_JUDICE_NINKE:
+          fb->buf[(y * fb->width) + x + 1] += quant_error * 7 / 48;
+          fb->buf[(y * fb->width) + x + 2] += quant_error * 5 / 48;
+          fb->buf[(y + 1) * fb->width + x - 2] += quant_error * 3 / 48;
+          fb->buf[(y + 1) * fb->width + x - 1] += quant_error * 5 / 48;
+          fb->buf[(y + 1) * fb->width + x] += quant_error * 7 / 48;
+          fb->buf[(y + 1) * fb->width + x + 1] += quant_error * 5 / 48;
+          fb->buf[(y + 1) * fb->width + x + 2] += quant_error * 3 / 48;
+          fb->buf[(y + 2) * fb->width + x - 2] += quant_error * 1 / 48;
+          fb->buf[(y + 2) * fb->width + x - 1] += quant_error * 3 / 48;
+          fb->buf[(y + 2) * fb->width + x] += quant_error * 5 / 48;
+          fb->buf[(y + 2) * fb->width + x + 1] += quant_error * 3 / 48;
+          fb->buf[(y + 2) * fb->width + x + 2] += quant_error * 1 / 48;
+          break;
+        case STUCKI:
+          fb->buf[(y * fb->width) + x + 1] += quant_error * 8 / 42;
+          fb->buf[(y * fb->width) + x + 2] += quant_error * 4 / 42;
+          fb->buf[(y + 1) * fb->width + x - 2] += quant_error * 2 / 42;
+          fb->buf[(y + 1) * fb->width + x - 1] += quant_error * 4 / 42;
+          fb->buf[(y + 1) * fb->width + x] += quant_error * 8 / 42;
+          fb->buf[(y + 1) * fb->width + x + 1] += quant_error * 4 / 42;
+          fb->buf[(y + 1) * fb->width + x + 2] += quant_error * 2 / 42;
+          fb->buf[(y + 2) * fb->width + x - 2] += quant_error * 1 / 42;
+          fb->buf[(y + 2) * fb->width + x - 1] += quant_error * 2 / 42;
+          fb->buf[(y + 2) * fb->width + x] += quant_error * 4 / 42;
+          fb->buf[(y + 2) * fb->width + x + 1] += quant_error * 2 / 42;
+          fb->buf[(y + 2) * fb->width + x + 2] += quant_error * 1 / 42;
+          break;
+        case FLOYD_STEINBERG:
+        default:
+          // Default to Floyd-Steinberg dithering if an invalid algorithm is selected
+          fb->buf[(y * fb->width) + x + 1] += quant_error * 7 / 16;
           fb->buf[(y + 1) * fb->width + x - 1] += quant_error * 3 / 16;
           fb->buf[(y + 1) * fb->width + x - 1] += quant_error * 3 / 16;
           fb->buf[(y + 1) * fb->width + x] += quant_error * 5 / 16;
           fb->buf[(y + 1) * fb->width + x] += quant_error * 5 / 16;
-          fb->buf[(y + 1) * fb->width + x + 1] += quant_error / 16;
-        }
+          fb->buf[(y + 1) * fb->width + x + 1] += quant_error * 1 / 16;
+          break;
       }
       }
-      break;
-    case 1: // Atkinson dithering
-      for (int y = 0; y < fb->height; ++y) {
-        for (int x = 0; x < fb->width; ++x) {
-          int current = y * fb->width + x;
-          uint8_t oldpixel = fb->buf[current];
-          uint8_t newpixel = oldpixel >= 128 ? 255 : 0;
-          fb->buf[current] = newpixel;
-          int quant_error = oldpixel - newpixel;
-
-          if (x + 1 < fb->width)
-            fb->buf[current + 1] += quant_error * 1 / 8;
-          if (x + 2 < fb->width)
-            fb->buf[current + 2] += quant_error * 1 / 8;
-          if (x > 0 && y + 1 < fb->height)
-            fb->buf[(y + 1) * fb->width + x - 1] += quant_error * 1 / 8;
-          if (y + 1 < fb->height)
-            fb->buf[(y + 1) * fb->width + x] += quant_error * 1 / 8;
-          if (y + 1 < fb->height && x + 1 < fb->width)
-            fb->buf[(y + 1) * fb->width + x + 1] += quant_error * 1 / 8;
-          if (y + 2 < fb->height)
-            fb->buf[(y + 2) * fb->width + x] += quant_error * 1 / 8;
-        }
-      }
-      break;
+    }
   }
   }
 }
 }
 
 
@@ -250,4 +244,4 @@ bool isDarkBit(uint8_t bit) {
   } else {
   } else {
     return bit < 128;
     return bit < 128;
   }
   }
-}
+}