diff --git a/src/main/cms/cms_menu_osd.c b/src/main/cms/cms_menu_osd.c index 7690b5aec3..e6e7c6ea75 100755 --- a/src/main/cms/cms_menu_osd.c +++ b/src/main/cms/cms_menu_osd.c @@ -205,6 +205,8 @@ static const OSD_Entry menuOsdElemsEntries[] = OSD_ELEMENT_ENTRY("MAP NORTH", OSD_MAP_NORTH), OSD_ELEMENT_ENTRY("MAP TAKE OFF", OSD_MAP_TAKEOFF), OSD_ELEMENT_ENTRY("RADAR", OSD_RADAR), + OSD_ELEMENT_ENTRY("MAP SCALE", OSD_MAP_SCALE), + OSD_ELEMENT_ENTRY("MAP REFERENCE", OSD_MAP_REFERENCE), #endif OSD_ELEMENT_ENTRY("EXPO", OSD_RC_EXPO), OSD_ELEMENT_ENTRY("YAW EXPO", OSD_RC_YAW_EXPO), diff --git a/src/main/io/osd.c b/src/main/io/osd.c index 229702ef78..861e20421c 100755 --- a/src/main/io/osd.c +++ b/src/main/io/osd.c @@ -170,6 +170,13 @@ static bool fullRedraw = false; static uint8_t armState; +typedef struct osdMapData_s { + uint32_t scale; + char referenceSymbol; +} osdMapData_t; + +static osdMapData_t osdMapData; + static displayPort_t *osdDisplayPort; #define AH_MAX_PITCH_DEFAULT 20 // Specify default maximum AHI pitch value displayed (degrees) @@ -953,8 +960,6 @@ static void osdDrawMap(int referenceHeading, uint8_t referenceSym, uint8_t cente const int charWidth = 12; const int charHeight = 18; - char buf[16]; - uint8_t minX = hMargin; uint8_t maxX = osdDisplayPort->cols - 1 - hMargin; uint8_t minY = vMargin; @@ -963,11 +968,6 @@ static void osdDrawMap(int referenceHeading, uint8_t referenceSym, uint8_t cente uint8_t midY = osdDisplayPort->rows / 2; // Fixed marks - if (referenceSym) { - displayWriteChar(osdDisplayPort, maxX, minY, SYM_DIRECTION); - displayWriteChar(osdDisplayPort, maxX, minY + 1, referenceSym); - } - displayWriteChar(osdDisplayPort, minX, maxY, SYM_SCALE); displayWriteChar(osdDisplayPort, midX, midY, centerSym); // First, erase the previous drawing. @@ -977,11 +977,6 @@ static void osdDrawMap(int referenceHeading, uint8_t referenceSym, uint8_t cente } uint32_t initialScale; - float scaleToUnit; - int scaleUnitDivisor; - char symUnscaled; - char symScaled; - int maxDecimals; const unsigned scaleMultiplier = 2; // We try to reduce the scale when the POI will be around half the distance // between the center and the closers map edge, to avoid too much jumping @@ -990,21 +985,11 @@ static void osdDrawMap(int referenceHeading, uint8_t referenceSym, uint8_t cente switch (osdConfig()->units) { case OSD_UNIT_IMPERIAL: initialScale = 16; // 16m ~= 0.01miles - scaleToUnit = 100 / 1609.3440f; // scale to 0.01mi for osdFormatCentiNumber() - scaleUnitDivisor = 0; - symUnscaled = SYM_MI; - symScaled = SYM_MI; - maxDecimals = 2; break; case OSD_UNIT_UK: FALLTHROUGH; case OSD_UNIT_METRIC: initialScale = 10; // 10m as initial scale - scaleToUnit = 100; // scale to cm for osdFormatCentiNumber() - scaleUnitDivisor = 1000; // Convert to km when scale gets bigger than 999m - symUnscaled = SYM_M; - symScaled = SYM_KM; - maxDecimals = 0; break; } @@ -1087,12 +1072,11 @@ static void osdDrawMap(int referenceHeading, uint8_t referenceSym, uint8_t cente } } - // Draw the used scale - bool scaled = osdFormatCentiNumber(buf, scale * scaleToUnit, scaleUnitDivisor, maxDecimals, 2, 3); - buf[3] = scaled ? symScaled : symUnscaled; - buf[4] = '\0'; - displayWrite(osdDisplayPort, minX + 1, maxY, buf); *usedScale = scale; + + // Update global map data for scale and reference + osdMapData.scale = scale; + osdMapData.referenceSymbol = referenceSym; } /* Draws a map with the home in the center and the craft moving around. @@ -2467,6 +2451,59 @@ static bool osdDrawSingleElement(uint8_t item) break; } + case OSD_MAP_SCALE: + { + float scaleToUnit; + int scaleUnitDivisor; + char symUnscaled; + char symScaled; + int maxDecimals; + + switch (osdConfig()->units) { + case OSD_UNIT_IMPERIAL: + scaleToUnit = 100 / 1609.3440f; // scale to 0.01mi for osdFormatCentiNumber() + scaleUnitDivisor = 0; + symUnscaled = SYM_MI; + symScaled = SYM_MI; + maxDecimals = 2; + break; + case OSD_UNIT_UK: + FALLTHROUGH; + case OSD_UNIT_METRIC: + scaleToUnit = 100; // scale to cm for osdFormatCentiNumber() + scaleUnitDivisor = 1000; // Convert to km when scale gets bigger than 999m + symUnscaled = SYM_M; + symScaled = SYM_KM; + maxDecimals = 0; + break; + } + buff[0] = SYM_SCALE; + if (osdMapData.scale > 0) { + bool scaled = osdFormatCentiNumber(&buff[1], osdMapData.scale * scaleToUnit, scaleUnitDivisor, maxDecimals, 2, 3); + buff[4] = scaled ? symScaled : symUnscaled; + // Make sure this is cleared if the map stops being drawn + osdMapData.scale = 0; + } else { + memset(&buff[1], '-', 4); + } + buff[5] = '\0'; + break; + } + case OSD_MAP_REFERENCE: + { + char referenceSymbol; + if (osdMapData.referenceSymbol) { + referenceSymbol = osdMapData.referenceSymbol; + // Make sure this is cleared if the map stops being drawn + osdMapData.referenceSymbol = 0; + } else { + referenceSymbol = '-'; + } + displayWriteChar(osdDisplayPort, elemPosX, elemPosY, SYM_DIRECTION); + displayWriteChar(osdDisplayPort, elemPosX, elemPosY + 1, referenceSymbol); + return true; + } + default: return false; } @@ -2522,7 +2559,7 @@ static uint8_t osdIncElementIndex(uint8_t elementIndex) if (elementIndex == OSD_TRIP_DIST) { elementIndex = OSD_ATTITUDE_PITCH; } - if (elementIndex == OSD_MAP_NORTH) { + if (elementIndex == OSD_WIND_SPEED_HORIZONTAL) { elementIndex = OSD_SAG_COMPENSATED_MAIN_BATT_VOLTAGE; } if (elementIndex == OSD_3D_SPEED) { diff --git a/src/main/io/osd.h b/src/main/io/osd.h index ecdf256bc8..09a2d0eccf 100755 --- a/src/main/io/osd.h +++ b/src/main/io/osd.h @@ -134,6 +134,8 @@ typedef enum { OSD_TEMP_SENSOR_7_TEMPERATURE, OSD_ALTITUDE_MSL, OSD_PLUS_CODE, + OSD_MAP_SCALE, + OSD_MAP_REFERENCE, OSD_ITEM_COUNT // MUST BE LAST } osd_items_e;