GameCounter/Source/lib/ssd1306xled/num2str.c

115 lines
4.0 KiB
C

/**
* NUM2STR - Functions to handle the conversion of numeric vales to strings.
*
* @created 2014-12-18
* @author Neven Boyanov
* @version 2016-04-17 (last modified)
*
* This is part of the Tinusaur/TinyAVRLib project.
*
* Copyright (c) 2016 Neven Boyanov, Tinusaur Team. All Rights Reserved.
* Distributed as open source software under MIT License, see LICENSE.txt file.
* Please, as a favor, retain the link http://tinusaur.org to The Tinusaur Project.
*
* Source code available at: https://bitbucket.org/tinusaur/tinyavrlib
*
*/
// ============================================================================
#include "num2str.h"
// ----------------------------------------------------------------------------
// NOTE: This implementation is borrowed from the LCDDDD library.
// Original source code at: https://bitbucket.org/boyanov/avr/src/default/lcdddd/src/lcdddd/lcdddd.h
uint8_t usint2decascii(uint16_t num, char *buffer)
{
const unsigned short powers[] = { 10000u, 1000u, 100u, 10u, 1u }; // The "const unsigned short" combination gives shortest code.
char digit; // "digit" is stored in a char array, so it should be of type char.
uint8_t digits = USINT2DECASCII_MAX_DIGITS - 1;
for (uint8_t pos = 0; pos < 5; pos++) // "pos" is index in array, so should be of type int.
{
digit = 0;
while (num >= powers[pos])
{
digit++;
num -= powers[pos];
}
// ---- CHOOSE (1), (2) or (3) ----
// CHOICE (1) Fixed width, zero padded result.
/*
buffer[pos] = digit + '0'; // Convert to ASCII
*/
// CHOICE (2) Fixed width, zero padded result, digits offset.
/*
buffer[pos] = digit + '0'; // Convert to ASCII
// Note: Determines the offset of the first significant digit.
if (digits == -1 && digit != 0) digits = pos;
// Note: Could be used for variable width, not padded, left aligned result.
*/
// CHOICE (3) Fixed width, space (or anything else) padded result, digits offset.
// Note: Determines the offset of the first significant digit.
// Note: Could be used for variable width, not padded, left aligned result.
if (digits == USINT2DECASCII_MAX_DIGITS - 1)
{
if (digit == 0)
{
if (pos < USINT2DECASCII_MAX_DIGITS - 1) // Check position, so single "0" will be handled properly.
digit = -16; // Use: "-16" for space (' '), "-3" for dash/minus ('-'), "0" for zero ('0'), etc. ...
}
else
{
digits = pos;
}
}
buffer[pos] = digit + '0'; // Convert to ASCII
}
// NOTE: The resulting ascii text should not be terminated with '\0' here.
// The provided buffer maybe part of a larger text in both directions.
return digits;
}
// ----------------------------------------------------------------------------
// NOTE: The buffer should be always at least MAX_DIGITS in length - the function works with 16-bit numbers.
uint8_t usint2binascii(uint16_t num, char *buffer) {
uint16_t power = 0x8000; // This is the 1000 0000 0000 0000 binary number.
char digit; // "digit" is stored in a char array, so it should be of type char.
uint8_t digits = USINT2BINASCII_MAX_DIGITS - 1;
for (uint8_t pos = 0; pos < USINT2BINASCII_MAX_DIGITS; pos++) { // "pos" is index in an array.
digit = 0;
if (num >= power) {
digit++;
num -= power;
}
// Fixed width, space ('0', or anything else) padded result, digits offset.
// Note: Determines the offset of the first significant digit.
// Note: Could be used for variable width, not padded, left aligned result.
if (digits == USINT2BINASCII_MAX_DIGITS - 1) {
if (digit == 0) {
if (pos < USINT2BINASCII_MAX_DIGITS - 1) // Check position, so single "0" will be handled properly.
digit = 0; // Use: "-16" for space (' '), "-3" for dash/minus ('-'), "0" for zero ('0'), etc.
} else {
digits = pos;
}
}
buffer[pos] = digit + '0'; // Convert to ASCII
power = power >> 1;
}
// NOTE: The resulting ascii text should not be terminated with '\0' here.
// The provided buffer maybe part of a larger text in both directions.
return digits;
}
// ============================================================================