Update '[ESP32] Camera Suite' to v1.1.0

This commit is contained in:
Cody Tolene
2023-07-27 22:25:37 -05:00
parent 99b203e25c
commit d4ff1e3a50
12 changed files with 119 additions and 500 deletions

View File

@@ -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, CameraSuiteViewIdCamera,
camera_suite_view_style_1_get_view(app->camera_suite_view_style_1)); camera_suite_view_camera_get_view(app->camera_suite_view_camera));
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));
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, CameraSuiteViewIdCamera);
view_dispatcher_remove_view(app->view_dispatcher, CameraSuiteViewIdScene2);
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_camera_free(app->camera_suite_view_camera);
camera_suite_view_style_2_free(app->camera_suite_view_style_2);
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);

View File

@@ -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_camera.h"
#include "views/camera_suite_view_style_2.h"
#include <assets_icons.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; CameraSuiteViewCamera* camera_suite_view_camera;
CameraSuiteViewStyle2* camera_suite_view_style_2;
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, CameraSuiteViewIdCamera,
CameraSuiteViewIdScene2,
CameraSuiteViewIdGuide, CameraSuiteViewIdGuide,
CameraSuiteViewIdSettings, CameraSuiteViewIdSettings,
} CameraSuiteViewId; } CameraSuiteViewId;

View File

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

View File

@@ -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( camera_suite_view_camera_set_callback(
app->camera_suite_view_style_1, camera_suite_view_style_1_callback, app); app->camera_suite_view_camera, camera_suite_view_camera_callback, app);
view_dispatcher_switch_to_view(app->view_dispatcher, CameraSuiteViewIdScene1); 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 CameraSuiteCustomEventSceneCameraLeft:
case CameraSuiteCustomEventSceneStyle1Right: case CameraSuiteCustomEventSceneCameraRight:
case CameraSuiteCustomEventSceneStyle1Up: case CameraSuiteCustomEventSceneCameraUp:
case CameraSuiteCustomEventSceneStyle1Down: case CameraSuiteCustomEventSceneCameraDown:
case CameraSuiteCustomEventSceneStyle1Ok: 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);
} }

View File

@@ -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, camera, Camera)
ADD_SCENE(camera_suite, style_2, Style_2)
ADD_SCENE(camera_suite, guide, Guide) ADD_SCENE(camera_suite, guide, Guide)
ADD_SCENE(camera_suite, settings, Settings) ADD_SCENE(camera_suite, settings, Settings)

View File

@@ -1,10 +1,8 @@
#include "../camera_suite.h" #include "../camera_suite.h"
enum SubmenuIndex { enum SubmenuIndex {
/** Atkinson Dithering Algorithm. */ /** Camera. */
SubmenuIndexSceneStyle1 = 10, SubmenuIndexSceneCamera = 10,
/** Floyd-Steinberg Dithering Algorithm. */
SubmenuIndexSceneStyle2,
/** 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); app->scene_manager, CameraSuiteSceneMenu, SubmenuIndexSceneCamera);
scene_manager_next_scene(app->scene_manager, CameraSuiteSceneStyle_1); scene_manager_next_scene(app->scene_manager, CameraSuiteSceneCamera);
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);
return true; return true;
} else if(event.event == SubmenuIndexGuide) { } else if(event.event == SubmenuIndexGuide) {
scene_manager_set_scene_state( scene_manager_set_scene_state(

View File

@@ -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);

View File

@@ -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);
}

View File

@@ -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; static CameraSuiteViewCamera* current_instance = NULL;
// Dithering type:
// 0 = Floyd Steinberg (default)
// 1 = Atkinson
static int current_dithering = 0;
struct CameraSuiteViewStyle1 { struct CameraSuiteViewCamera {
CameraSuiteViewStyle1Callback callback; 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( void camera_suite_view_camera_set_callback(
CameraSuiteViewStyle1* instance, CameraSuiteViewCamera* instance,
CameraSuiteViewStyle1Callback callback, CameraSuiteViewCameraCallback callback,
void* context) { void* context) {
furi_assert(instance); furi_assert(instance);
furi_assert(callback); furi_assert(callback);
@@ -32,7 +28,29 @@ 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) { // Function to draw pixels on the canvas based on camera orientation
static void draw_pixel_by_orientation(Canvas* canvas, uint8_t x, uint8_t y, uint8_t orientation) {
switch(orientation) {
case 0: // Camera rotated 0 degrees (right side up, default)
canvas_draw_dot(canvas, x, y);
break;
case 1: // Camera rotated 90 degrees
canvas_draw_dot(canvas, y, FRAME_WIDTH - 1 - x);
break;
case 2: // Camera rotated 180 degrees (upside down)
canvas_draw_dot(canvas, FRAME_WIDTH - 1 - x, FRAME_HEIGHT - 1 - y);
break;
case 3: // Camera rotated 270 degrees
canvas_draw_dot(canvas, FRAME_HEIGHT - 1 - y, x);
break;
default:
break;
}
}
static void camera_suite_view_camera_draw(Canvas* canvas, void* _model) {
UartDumpModel* model = _model;
// Clear the screen. // Clear the screen.
canvas_set_color(canvas, ColorBlack); canvas_set_color(canvas, ColorBlack);
@@ -41,60 +59,17 @@ static void camera_suite_view_style_1_draw(Canvas* canvas, UartDumpModel* model)
CameraSuite* app = current_instance->context; CameraSuite* app = current_instance->context;
// Draw the pixels with rotation.
for(size_t p = 0; p < FRAME_BUFFER_LENGTH; ++p) { for(size_t p = 0; p < FRAME_BUFFER_LENGTH; ++p) {
uint8_t x = p % ROW_BUFFER_LENGTH; // 0 .. 15 uint8_t x = p % ROW_BUFFER_LENGTH; // 0 .. 15
uint8_t y = p / ROW_BUFFER_LENGTH; // 0 .. 63 uint8_t y = p / ROW_BUFFER_LENGTH; // 0 .. 63
// Apply rotation
int16_t rotated_x, rotated_y;
switch(app->orientation) {
case 1: // 90 degrees
rotated_x = y;
rotated_y = FRAME_WIDTH - 1 - x;
break;
case 2: // 180 degrees
rotated_x = FRAME_WIDTH - 1 - x;
rotated_y = FRAME_HEIGHT - 1 - y;
break;
case 3: // 270 degrees
rotated_x = FRAME_HEIGHT - 1 - y;
rotated_y = x;
break;
case 0: // 0 degrees
default:
rotated_x = x;
rotated_y = y;
break;
}
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 draw_pixel_by_orientation(canvas, (x * 8) + i, y, app->orientation);
uint16_t screen_x, screen_y;
switch(app->orientation) {
case 1: // 90 degrees
screen_x = rotated_x;
screen_y = FRAME_HEIGHT - 8 + (rotated_y * 8) + i;
break;
case 2: // 180 degrees
screen_x = FRAME_WIDTH - 8 + (rotated_x * 8) + i;
screen_y = FRAME_HEIGHT - 1 - rotated_y;
break;
case 3: // 270 degrees
screen_x = FRAME_WIDTH - 1 - rotated_x;
screen_y = rotated_y * 8 + i;
break;
case 0: // 0 degrees
default:
screen_x = rotated_x * 8 + i;
screen_y = rotated_y;
break;
}
canvas_draw_dot(canvas, screen_x, screen_y);
} }
} }
} }
// Draw the guide if the camera is not initialized. // Draw the guide if the camera is not initialized.
if(!model->initialized) { if(!model->initialized) {
canvas_draw_icon(canvas, 74, 16, &I_DolphinCommon_56x48); canvas_draw_icon(canvas, 74, 16, &I_DolphinCommon_56x48);
@@ -107,15 +82,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 +119,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 +134,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 +149,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 +164,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 +179,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) { // Switch dithering types.
data[0] = 'd'; // Update to Floyd Steinberg dithering. data[0] = 'D';
current_dithering = 1;
} else {
data[0] = 'D'; // Update to Atkinson dithering.
current_dithering = 0;
}
with_view_model( with_view_model(
instance->view, instance->view,
UartDumpModel * model, UartDumpModel * model,
@@ -224,7 +194,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 +207,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`. // Cast `context` to `CameraSuiteViewCamera*` and store it in `instance`.
CameraSuiteViewStyle1* instance = (CameraSuiteViewStyle1*)context; 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 +229,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 +237,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`. // Cast `context` to `CameraSuiteViewCamera*` and store it in `instance`.
CameraSuiteViewStyle1* instance = context; 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 +289,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 +318,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() { CameraSuiteViewCamera* camera_suite_view_camera_alloc() {
CameraSuiteViewStyle1* instance = malloc(sizeof(CameraSuiteViewStyle1)); CameraSuiteViewCamera* instance = malloc(sizeof(CameraSuiteViewCamera));
instance->view = view_alloc(); instance->view = view_alloc();
@@ -364,15 +337,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_draw_callback(instance->view, (ViewDrawCallback)camera_suite_view_camera_draw);
view_set_input_callback(instance->view, camera_suite_view_style_1_input); view_set_input_callback(instance->view, camera_suite_view_camera_input);
view_set_enter_callback(instance->view, camera_suite_view_style_1_enter); view_set_enter_callback(instance->view, camera_suite_view_camera_enter);
view_set_exit_callback(instance->view, camera_suite_view_style_1_exit); 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 +359,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 +368,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;
} }

View File

@@ -19,11 +19,12 @@
#define FRAME_WIDTH 128 #define FRAME_WIDTH 128
#define FRAME_HEIGHT 64 #define FRAME_HEIGHT 64
#define FRAME_BIT_DEPTH 1 #define FRAME_BIT_DEPTH 1
#define FRAME_BUFFER_LENGTH \ #define FRAME_BUFFER_LENGTH 1024
(FRAME_WIDTH * FRAME_HEIGHT * FRAME_BIT_DEPTH / 8) // 128*64*1 / 8 = 1024 #define ROW_BUFFER_LENGTH 16
#define ROW_BUFFER_LENGTH (FRAME_WIDTH / 8) // 128/8 = 16 #define RING_BUFFER_LENGTH 19
#define RING_BUFFER_LENGTH (ROW_BUFFER_LENGTH + 3) // ROW_BUFFER_LENGTH + Header => 16 + 3 = 19 #define LAST_ROW_INDEX 1008
#define LAST_ROW_INDEX (FRAME_BUFFER_LENGTH - ROW_BUFFER_LENGTH) // 1024 - 16 = 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( void camera_suite_view_camera_set_callback(
CameraSuiteViewStyle1* camera_suite_view_style_1, CameraSuiteViewCamera* camera_suite_view_camera,
CameraSuiteViewStyle1Callback callback, 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

View File

@@ -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;
}

View File

@@ -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);