diff --git a/main/button_events.h b/main/button_events.h index 8b835ff4..fbbe94f4 100644 --- a/main/button_events.h +++ b/main/button_events.h @@ -137,6 +137,7 @@ typedef enum { BTN_SETTINGS_DISPLAY_EXIT, BTN_SETTINGS_DISPLAY_BRIGHTNESS, BTN_SETTINGS_DISPLAY_ORIENTATION, + BTN_SETTINGS_DISPLAY_CAMERA_ROTATE, BTN_SETTINGS_DISPLAY_THEME, BTN_SETTINGS_XPUB_EXPORT, BTN_SETTINGS_QR_PINSERVER, diff --git a/main/camera.c b/main/camera.c index 82c7f43e..5bae933b 100644 --- a/main/camera.c +++ b/main/camera.c @@ -9,6 +9,7 @@ #include "jade_tasks.h" #include "power.h" #include "sensitive.h" +#include "storage.h" #include "ui.h" #include "utils/event.h" #include "utils/malloc_ext.h" @@ -376,8 +377,12 @@ static void jade_camera_task(void* data) typedef void (*copy_camera_image_fn_t)( uint8_t[DISPLAY_IMAGE_HEIGHT][DISPLAY_IMAGE_WIDTH], const uint8_t[CAMERA_IMAGE_HEIGHT][CAMERA_IMAGE_WIDTH]); + // The user may have persisted an extra 180-degree rotation to correct for camera + // modules which can be physically mounted either way up (eg. on some DIY units). + // This composes with any flipped display orientation, hence the inequality. + const bool camera_rotated = storage_get_gui_flags() & GUI_FLAGS_CAMERA_ROTATED; copy_camera_image_fn_t copy_camera_image - = gui_get_flipped_orientation() ? COPY_CAMERA_IMAGE_FLIPPED : COPY_CAMERA_IMAGE_STRAIGHT; + = (gui_get_flipped_orientation() != camera_rotated) ? COPY_CAMERA_IMAGE_FLIPPED : COPY_CAMERA_IMAGE_STRAIGHT; camera_task_config_t* const camera_config = (camera_task_config_t*)data; JADE_ASSERT(camera_config->fn_process); diff --git a/main/process/dashboard.c b/main/process/dashboard.c index 43fac712..2a4ec16a 100644 --- a/main/process/dashboard.c +++ b/main/process/dashboard.c @@ -1925,6 +1925,16 @@ static void handle_flip_orientation(void) } } +#if defined(CONFIG_HAS_CAMERA) && !defined(CONFIG_BOARD_TYPE_JADE_ANY) +static void handle_camera_rotate(void) +{ + // Toggle the extra 180-degree camera image rotation - takes effect + // next time the camera is used + const uint8_t gui_flags = storage_get_gui_flags(); + storage_set_gui_flags(gui_flags ^ GUI_FLAGS_CAMERA_ROTATED); +} +#endif + #ifdef CONFIG_HAS_CAMERA static void handle_pinserver_scan(void) { @@ -2302,6 +2312,14 @@ static void handle_settings(const bool startup_menu) handle_flip_orientation(); break; +#if defined(CONFIG_HAS_CAMERA) && !defined(CONFIG_BOARD_TYPE_JADE_ANY) + case BTN_SETTINGS_DISPLAY_CAMERA_ROTATE: + handle_camera_rotate(); + // remake parent screen to update the menu item label + act = make_display_settings_activity(); + break; +#endif + case BTN_SETTINGS_DISPLAY_THEME: handle_display_theme(); // remake parent screen to update colours diff --git a/main/storage.h b/main/storage.h index 538eb7c9..9343e805 100644 --- a/main/storage.h +++ b/main/storage.h @@ -13,6 +13,7 @@ #define BLE_ENABLED 0x1 #define GUI_FLAGS_THEMES_MASK 0x7 +#define GUI_FLAGS_CAMERA_ROTATED 0x20 #define GUI_FLAGS_FLIP_ORIENTATION 0x40 #define GUI_FLAGS_USE_WHEEL_CLICK 0x80 diff --git a/main/ui/dashboard.c b/main/ui/dashboard.c index 2001468c..277f177b 100644 --- a/main/ui/dashboard.c +++ b/main/ui/dashboard.c @@ -2,6 +2,7 @@ #include "../button_events.h" #include "../display.h" #include "../jade_assert.h" +#include "../storage.h" #include "../ui.h" #include "process.h" #include "utils/malloc_ext.h" @@ -392,6 +393,13 @@ gui_activity_t* make_display_settings_activity(void) btn_data_t hdrbtns[] = { { .txt = "=", .font = JADE_SYMBOLS_16x16_FONT, .ev_id = BTN_SETTINGS_DISPLAY_EXIT }, { .txt = NULL, .font = GUI_DEFAULT_FONT, .ev_id = GUI_BUTTON_EVENT_NONE } }; +#if defined(CONFIG_HAS_CAMERA) && !defined(CONFIG_BOARD_TYPE_JADE_ANY) + // The label doubles as the state indicator - shows 'Camera Rotated' while + // the extra 180-degree camera rotation is active + const char* const camera_btn_label + = (storage_get_gui_flags() & GUI_FLAGS_CAMERA_ROTATED) ? "Camera Rotated" : "Rotate Camera"; +#endif + // NOTE: Only boards listed here have brightness controls // NOTE: Jade v1.1's do not support Flip Orientation because of issues with screen offsets #if defined(CONFIG_BOARD_TYPE_JADE_V2_ANY) || defined(CONFIG_BOARD_TYPE_WS_TOUCH_LCD2) \ @@ -399,6 +407,9 @@ gui_activity_t* make_display_settings_activity(void) btn_data_t menubtns[] = { { .txt = "Display Brightness", .font = GUI_DEFAULT_FONT, .ev_id = BTN_SETTINGS_DISPLAY_BRIGHTNESS }, { .txt = "Flip Orientation", .font = GUI_DEFAULT_FONT, .ev_id = BTN_SETTINGS_DISPLAY_ORIENTATION }, +#if defined(CONFIG_HAS_CAMERA) && !defined(CONFIG_BOARD_TYPE_JADE_ANY) + { .txt = camera_btn_label, .font = GUI_DEFAULT_FONT, .ev_id = BTN_SETTINGS_DISPLAY_CAMERA_ROTATE }, +#endif { .txt = "Theme", .font = GUI_DEFAULT_FONT, .ev_id = BTN_SETTINGS_DISPLAY_THEME } }; #elif defined(CONFIG_BOARD_TYPE_JADE_V1_1) btn_data_t menubtns[] @@ -409,6 +420,9 @@ gui_activity_t* make_display_settings_activity(void) #else // DIY units btn_data_t menubtns[] = { { .txt = "Flip Orientation", .font = GUI_DEFAULT_FONT, .ev_id = BTN_SETTINGS_DISPLAY_ORIENTATION }, +#if defined(CONFIG_HAS_CAMERA) + { .txt = camera_btn_label, .font = GUI_DEFAULT_FONT, .ev_id = BTN_SETTINGS_DISPLAY_CAMERA_ROTATE }, +#endif { .txt = "Theme", .font = GUI_DEFAULT_FONT, .ev_id = BTN_SETTINGS_DISPLAY_THEME } }; #endif