2 * This file is part of INAV
4 * INAV is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
9 * INAV is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with Cleanflight. If not, see <http://www.gnu.org/licenses/>.
18 #include "io/osd_utils.h"
20 #include "common/maths.h"
21 #include "common/typeconversion.h"
22 #include "drivers/osd_symbols.h"
23 #include "io/displayport_msp_dji_compat.h"
25 #if defined(USE_OSD) || defined(OSD_UNIT_TEST)
27 int digitCount(int32_t value
)
41 bool osdFormatCentiNumber(char *buff
, int32_t centivalue
, uint32_t scale
, int maxDecimals
, int maxScaledDecimals
, int length
, bool leadingZeros
)
45 int decimals
= maxDecimals
;
46 bool negative
= false;
48 bool explicitDecimal
= isDJICompatibleVideoSystem(osdConfig());
54 centivalue
= -centivalue
;
58 int32_t integerPart
= centivalue
/ 100;
60 int32_t millis
= (centivalue
% 100) * 10;
62 int digits
= digitCount(integerPart
);
63 int remaining
= length
- digits
;
64 if (explicitDecimal
) {
68 if (remaining
< 0 && scale
> 0) {
71 decimals
= maxScaledDecimals
;
72 integerPart
= integerPart
/ scale
;
73 // Multiply by 10 to get 3 decimal digits
74 millis
= ((centivalue
% (100 * scale
)) * 10) / scale
;
75 digits
= digitCount(integerPart
);
76 remaining
= length
- digits
;
77 if (explicitDecimal
) {
83 decimals
= MIN(remaining
, MIN(decimals
, 3));
84 remaining
-= decimals
;
86 // Done counting. Time to write the characters.
87 // Write spaces at the start
88 while (remaining
> 0) {
98 // Keep number right aligned and correct length
99 if(explicitDecimal
&& decimals
== 0) {
100 uint8_t blank_spaces
= ptr
- buff
;
101 int8_t rem_spaces
= length
- (digits
+ blank_spaces
);
102 // Add any needed remaining leading spaces
103 while(rem_spaces
> 0)
116 // Write the minus sign if required
121 // Now write the digits.
122 ui2a(integerPart
, 10, 0, ptr
);
126 if (explicitDecimal
) {
130 *(ptr
- 1) += SYM_ZERO_HALF_TRAILING_DOT
- '0';
133 int factor
= 3; // we're getting the decimal part in millis first
134 while (decimals
< factor
) {
138 int decimalDigits
= digitCount(millis
);
139 while (decimalDigits
< decimals
) {
144 ui2a(millis
, 10, 0, ptr
);
145 if (!explicitDecimal
) {
146 *dec
+= SYM_ZERO_HALF_LEADING_DOT
- '0';