From 377f5cba7f24868c7d431842e914cbca0a5f2da7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alberto=20Garci=CC=81a=20Hierro?= Date: Wed, 25 Mar 2020 16:41:54 +0000 Subject: [PATCH] [CANVAS] Add alternate AHI style with a single line --- src/main/fc/settings.yaml | 6 ++++ src/main/io/osd.c | 2 +- src/main/io/osd.h | 6 ++++ src/main/io/osd_canvas.c | 69 ++++++++++++++++++++++++++++++++++----- 4 files changed, 73 insertions(+), 10 deletions(-) diff --git a/src/main/fc/settings.yaml b/src/main/fc/settings.yaml index 66e2ec87cc..88ce41d6b8 100644 --- a/src/main/fc/settings.yaml +++ b/src/main/fc/settings.yaml @@ -138,6 +138,9 @@ tables: - name: pidTypeTable values: ["NONE", "PID", "PIFF", "AUTO"] enum: pidType_e + - name: osd_ahi_style + values: ["DEFAULT", "LINE"] + enum: osd_ahi_style_e groups: - name: PG_GYRO_CONFIG @@ -1999,6 +2002,9 @@ groups: min: 10 max: 13 + - name: osd_ahi_style + table: osd_ahi_style + - name: PG_SYSTEM_CONFIG type: systemConfig_t headers: ["fc/config.h"] diff --git a/src/main/io/osd.c b/src/main/io/osd.c index df93a1d59f..7da898ebc4 100755 --- a/src/main/io/osd.c +++ b/src/main/io/osd.c @@ -198,7 +198,7 @@ static bool osdDisplayHasCanvas; #define AH_SIDEBAR_WIDTH_POS 7 #define AH_SIDEBAR_HEIGHT_POS 3 -PG_REGISTER_WITH_RESET_FN(osdConfig_t, osdConfig, PG_OSD_CONFIG, 10); +PG_REGISTER_WITH_RESET_FN(osdConfig_t, osdConfig, PG_OSD_CONFIG, 11); static int digitCount(int32_t value) { diff --git a/src/main/io/osd.h b/src/main/io/osd.h index 43fa41274c..7b26c452ec 100755 --- a/src/main/io/osd.h +++ b/src/main/io/osd.h @@ -187,6 +187,11 @@ typedef enum { OSD_ALIGN_RIGHT } osd_alignment_e; +typedef enum { + OSD_AHI_STYLE_DEFAULT, + OSD_AHI_STYLE_LINE, +} osd_ahi_style_e; + typedef struct osdConfig_s { // Layouts uint16_t item_pos[OSD_LAYOUT_COUNT][OSD_ITEM_COUNT]; @@ -245,6 +250,7 @@ typedef struct osdConfig_s { bool osd_failsafe_switch_layout; uint8_t plus_code_digits; // Number of digits to use in OSD_PLUS_CODE + uint8_t osd_ahi_style; } osdConfig_t; PG_DECLARE(osdConfig_t, osdConfig); diff --git a/src/main/io/osd_canvas.c b/src/main/io/osd_canvas.c index c4d562be45..4d42b6daf4 100644 --- a/src/main/io/osd_canvas.c +++ b/src/main/io/osd_canvas.c @@ -32,6 +32,7 @@ #define AHI_MIN_DRAW_INTERVAL_MS 100 #define AHI_MAX_DRAW_INTERVAL_MS 1000 +#define AHI_CROSSHAIR_MARGIN 6 #include "common/log.h" #include "common/maths.h" @@ -45,6 +46,7 @@ #include "drivers/time.h" #include "io/osd_common.h" +#include "io/osd.h" void osdCanvasDrawVarioShape(displayCanvas_t *canvas, unsigned ex, unsigned ey, float zvel, bool erase) { @@ -162,7 +164,6 @@ static void osdDrawArtificialHorizonShapes(displayCanvas_t *canvas, float pitchA { int barWidth = (OSD_AHI_WIDTH - 1) * canvas->gridElementWidth; int levelBarWidth = barWidth * (3.0/4); - int crosshairMargin = 6; float pixelsPerDegreeLevel = 3.5f; int borderSize = 3; char buf[12]; @@ -220,9 +221,9 @@ static void osdDrawArtificialHorizonShapes(displayCanvas_t *canvas, float pitchA if (ii == 0) { displayCanvasSetLineOutlineType(canvas, DISPLAY_CANVAS_OUTLINE_TYPE_BOTTOM); displayCanvasMoveToPoint(canvas, -barWidth / 2, 0); - displayCanvasStrokeLineToPoint(canvas, -crosshairMargin, 0); + displayCanvasStrokeLineToPoint(canvas, -AHI_CROSSHAIR_MARGIN, 0); displayCanvasMoveToPoint(canvas, barWidth / 2, 0); - displayCanvasStrokeLineToPoint(canvas, crosshairMargin, 0); + displayCanvasStrokeLineToPoint(canvas, AHI_CROSSHAIR_MARGIN, 0); continue; } @@ -257,6 +258,48 @@ static void osdDrawArtificialHorizonShapes(displayCanvas_t *canvas, float pitchA displayCanvasContextPop(canvas); } +void osdDrawArtificialHorizonLine(displayCanvas_t *canvas, float pitchAngle, float rollAngle, bool erase) +{ + int barWidth = (OSD_AHI_WIDTH - 1) * canvas->gridElementWidth; + int maxHeight = canvas->height; + float pixelsPerDegreeLevel = 1.5f; + int maxWidth = (OSD_AHI_WIDTH + 1) * canvas->gridElementWidth; + + int lx = (canvas->width - maxWidth) / 2; + + displayCanvasContextPush(canvas); + + displayCanvasClipToRect(canvas, lx, 0, maxWidth, maxHeight); + osdGridBufferClearPixelRect(canvas, lx, 0, maxWidth, maxHeight); + + if (erase) { + displayCanvasSetStrokeColor(canvas, DISPLAY_CANVAS_COLOR_TRANSPARENT); + displayCanvasSetLineOutlineColor(canvas, DISPLAY_CANVAS_COLOR_TRANSPARENT); + } else { + displayCanvasSetStrokeColor(canvas, DISPLAY_CANVAS_COLOR_WHITE); + displayCanvasSetLineOutlineColor(canvas, DISPLAY_CANVAS_COLOR_BLACK); + } + + float pitchDegrees = RADIANS_TO_DEGREES(pitchAngle); + float pitchOffset = -pitchDegrees * pixelsPerDegreeLevel; + float translateX = canvas->width / 2; + float translateY = canvas->height / 2; + + displayCanvasCtmTranslate(canvas, 0, pitchOffset); + displayCanvasCtmRotate(canvas, rollAngle); + displayCanvasCtmTranslate(canvas, translateX, translateY); + + + displayCanvasSetStrokeWidth(canvas, 2); + displayCanvasSetLineOutlineType(canvas, DISPLAY_CANVAS_OUTLINE_TYPE_BOTTOM); + displayCanvasMoveToPoint(canvas, -barWidth / 2, 0); + displayCanvasStrokeLineToPoint(canvas, -AHI_CROSSHAIR_MARGIN, 0); + displayCanvasMoveToPoint(canvas, barWidth / 2, 0); + displayCanvasStrokeLineToPoint(canvas, AHI_CROSSHAIR_MARGIN, 0); + + displayCanvasContextPop(canvas); +} + void osdCanvasDrawArtificialHorizon(displayPort_t *display, displayCanvas_t *canvas, const osdDrawPoint_t *p, float pitchAngle, float rollAngle) { UNUSED(display); @@ -271,12 +314,20 @@ void osdCanvasDrawArtificialHorizon(displayPort_t *display, displayCanvas_t *can float totalError = fabsf(prevPitchAngle - pitchAngle) + fabsf(prevRollAngle - rollAngle); if ((now > nextDrawMinMs && totalError > 0.05f)|| now > nextDrawMaxMs) { - - int x, y, w, h; - osdArtificialHorizonRect(canvas, &x, &y, &w, &h); - displayCanvasClearRect(canvas, x, y, w, h); - - osdDrawArtificialHorizonShapes(canvas, pitchAngle, rollAngle); + switch ((osd_ahi_style_e)osdConfig()->osd_ahi_style) { + case OSD_AHI_STYLE_DEFAULT: + { + int x, y, w, h; + osdArtificialHorizonRect(canvas, &x, &y, &w, &h); + displayCanvasClearRect(canvas, x, y, w, h); + osdDrawArtificialHorizonShapes(canvas, pitchAngle, rollAngle); + break; + } + case OSD_AHI_STYLE_LINE: + osdDrawArtificialHorizonLine(canvas, prevPitchAngle, prevRollAngle, true); + osdDrawArtificialHorizonLine(canvas, pitchAngle, rollAngle, false); + break; + } prevPitchAngle = pitchAngle; prevRollAngle = rollAngle; nextDrawMinMs = now + AHI_MIN_DRAW_INTERVAL_MS;