69 lines
1.7 KiB
C++
69 lines
1.7 KiB
C++
#include <cstdint>
|
|
|
|
#include "graphic.hpp"
|
|
#include "font.hpp"
|
|
|
|
// left-align (with fill)
|
|
// right-align
|
|
|
|
struct bcd_t {
|
|
uint32_t digits;
|
|
int32_t length;
|
|
|
|
auto operator<=>(const bcd_t&) const = default;
|
|
};
|
|
|
|
static inline constexpr bcd_t int_to_bcd(int32_t n)
|
|
{
|
|
if (n < 0) n = 0; // are there negative numbers in pokemon?
|
|
if (n == 0) return { 0, 1 };
|
|
uint32_t bcd = 0;
|
|
|
|
int32_t index = 0;
|
|
while (n != 0) {
|
|
bcd |= (n % 10) << (4 * index);
|
|
n /= 10;
|
|
index += 1;
|
|
}
|
|
return { bcd, index };
|
|
}
|
|
|
|
static_assert(int_to_bcd(0) == (bcd_t){0x0, 1});
|
|
static_assert(int_to_bcd(9) == (bcd_t){0x9, 1});
|
|
static_assert(int_to_bcd(20) == (bcd_t){0x20, 2});
|
|
static_assert(int_to_bcd(512) == (bcd_t){0x512, 3});
|
|
|
|
void draw_number_right_align(const uint32_t base_pattern,
|
|
const screen_cell_t& pos,
|
|
const int32_t n,
|
|
const int32_t width,
|
|
const uint8_t fill)
|
|
{
|
|
const bcd_t bcd = int_to_bcd(n);
|
|
|
|
int32_t index = 0;
|
|
while (index < width) {
|
|
const uint8_t digit = (index < bcd.length)
|
|
? ascii_to_font('0' + ((bcd.digits >> (4 * index)) & 0b1111))
|
|
: fill;
|
|
index++;
|
|
put_char(base_pattern, (pos.x + width) - index, pos.y, digit);
|
|
}
|
|
}
|
|
|
|
void draw_number_left_align(const uint32_t base_pattern,
|
|
const screen_cell_t& pos,
|
|
const int32_t n,
|
|
const int32_t width)
|
|
{
|
|
const bcd_t bcd = int_to_bcd(n);
|
|
|
|
int32_t index = 0;
|
|
int32_t length = width < bcd.length ? width : bcd.length;
|
|
while (index < length) {
|
|
const uint8_t digit = ascii_to_font('0' + ((bcd.digits >> (4 * index)) & 0b1111));
|
|
index++;
|
|
put_char(base_pattern, pos.x + (length - index), pos.y, digit);
|
|
}
|
|
}
|