1
0
Fork 0
mirror of https://github.com/iNavFlight/inav.git synced 2025-07-24 00:35:34 +03:00
inav/src/main/io/osd_utils.c
Darren Lines 524b0d0bf4 Final updates
- Converted Maths.h to tabs
- Added leading zeros to odometer and decimal place
2023-08-28 17:48:55 +01:00

151 lines
No EOL
3.9 KiB
C

/*
* This file is part of INAV
*
* INAV is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* INAV is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Cleanflight. If not, see <http://www.gnu.org/licenses/>.
*/
#include "io/osd_utils.h"
#include "common/maths.h"
#include "common/typeconversion.h"
#include "drivers/osd_symbols.h"
#include "io/displayport_msp_bf_compat.h"
#if defined(USE_OSD) || defined(OSD_UNIT_TEST)
int digitCount(int32_t value)
{
int digits = 1;
while(1) {
value = value / 10;
if (value == 0) {
break;
}
digits++;
}
return digits;
}
bool osdFormatCentiNumber(char *buff, int32_t centivalue, uint32_t scale, int maxDecimals, int maxScaledDecimals, int length, bool leadingZeros)
{
char *ptr = buff;
char *dec;
int decimals = maxDecimals;
bool negative = false;
bool scaled = false;
bool explicitDecimal = isBfCompatibleVideoSystem(osdConfig());
buff[length] = '\0';
if (centivalue < 0) {
negative = true;
centivalue = -centivalue;
length--;
}
int32_t integerPart = centivalue / 100;
// 3 decimal digits
int32_t millis = (centivalue % 100) * 10;
int digits = digitCount(integerPart);
int remaining = length - digits;
if (explicitDecimal) {
remaining--;
}
if (remaining < 0 && scale > 0) {
// Reduce by scale
scaled = true;
decimals = maxScaledDecimals;
integerPart = integerPart / scale;
// Multiply by 10 to get 3 decimal digits
millis = ((centivalue % (100 * scale)) * 10) / scale;
digits = digitCount(integerPart);
remaining = length - digits;
if (explicitDecimal) {
remaining--;
}
}
// 3 decimals at most
decimals = MIN(remaining, MIN(decimals, 3));
remaining -= decimals;
// Done counting. Time to write the characters.
// Write spaces at the start
while (remaining > 0) {
if (leadingZeros)
*ptr = '0';
else
*ptr = SYM_BLANK;
ptr++;
remaining--;
}
// Keep number right aligned and correct length
if(explicitDecimal && decimals == 0) {
uint8_t blank_spaces = ptr - buff;
int8_t rem_spaces = length - (digits + blank_spaces);
// Add any needed remaining leading spaces
while(rem_spaces > 0)
{
if (leadingZeros)
*ptr = '0';
else
*ptr = SYM_BLANK;
ptr++;
remaining--;
rem_spaces--;
}
}
// Write the minus sign if required
if (negative) {
*ptr = '-';
ptr++;
}
// Now write the digits.
ui2a(integerPart, 10, 0, ptr);
ptr += digits;
if (decimals > 0) {
if (explicitDecimal) {
*ptr = '.';
ptr++;
} else {
*(ptr - 1) += SYM_ZERO_HALF_TRAILING_DOT - '0';
}
dec = ptr;
int factor = 3; // we're getting the decimal part in millis first
while (decimals < factor) {
factor--;
millis /= 10;
}
int decimalDigits = digitCount(millis);
while (decimalDigits < decimals) {
decimalDigits++;
*ptr = '0';
ptr++;
}
ui2a(millis, 10, 0, ptr);
if (!explicitDecimal) {
*dec += SYM_ZERO_HALF_LEADING_DOT - '0';
}
}
return scaled;
}
#endif