Files
dangerzone/src/engine/text.c
T
2026-10-05 02:24:13 +02:00

142 lines
4.8 KiB
C

// rendering characters in the framebuffer
#include "engine.h"
#include <stdint.h>
/*
* each character has 8 rows
* only the lower 4 bits of each byte are used
*/
static const uint8_t font[128][FONT_ROWS] = {
[' '] = { 0, 0, 0, 0, 0, 0, 0 },
['A'] = { 0x0E, 0x11, 0x11, 0x1F, 0x11, 0x11, 0x11 },
['B'] = { 0x1E, 0x11, 0x11, 0x1E, 0x11, 0x11, 0x1E },
['C'] = { 0x0F, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0F },
['D'] = { 0x1E, 0x11, 0x11, 0x11, 0x11, 0x11, 0x1E },
['E'] = { 0x1F, 0x10, 0x10, 0x1E, 0x10, 0x10, 0x1F },
['F'] = { 0x1F, 0x10, 0x10, 0x1E, 0x10, 0x10, 0x10 },
['G'] = { 0x0F, 0x10, 0x10, 0x17, 0x11, 0x11, 0x0F },
['H'] = { 0x11, 0x11, 0x11, 0x1F, 0x11, 0x11, 0x11 },
['I'] = { 0x1F, 0x04, 0x04, 0x04, 0x04, 0x04, 0x1F },
['J'] = { 0x01, 0x01, 0x01, 0x01, 0x11, 0x11, 0x0E },
['K'] = { 0x11, 0x12, 0x14, 0x18, 0x14, 0x12, 0x11 },
['L'] = { 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x1F },
['M'] = { 0x11, 0x1B, 0x15, 0x15, 0x11, 0x11, 0x11 },
['N'] = { 0x11, 0x19, 0x15, 0x13, 0x11, 0x11, 0x11 },
['O'] = { 0x0E, 0x11, 0x11, 0x11, 0x11, 0x11, 0x0E },
['P'] = { 0x1E, 0x11, 0x11, 0x1E, 0x10, 0x10, 0x10 },
['Q'] = { 0x0E, 0x11, 0x11, 0x11, 0x15, 0x12, 0x0D },
['R'] = { 0x1E, 0x11, 0x11, 0x1E, 0x14, 0x12, 0x11 },
['S'] = { 0x0F, 0x10, 0x10, 0x0E, 0x01, 0x01, 0x1E },
['T'] = { 0x1F, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04 },
['U'] = { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x0E },
['V'] = { 0x11, 0x11, 0x11, 0x11, 0x11, 0x0A, 0x04 },
['W'] = { 0x11, 0x11, 0x11, 0x15, 0x15, 0x15, 0x0A },
['X'] = { 0x11, 0x11, 0x0A, 0x04, 0x0A, 0x11, 0x11 },
['Y'] = { 0x11, 0x11, 0x0A, 0x04, 0x04, 0x04, 0x04 },
['Z'] = { 0x1F, 0x01, 0x02, 0x04, 0x08, 0x10, 0x1F },
['0'] = { 0x0E, 0x11, 0x13, 0x15, 0x19, 0x11, 0x0E },
['1'] = { 0x04, 0x0C, 0x04, 0x04, 0x04, 0x04, 0x0E },
['2'] = { 0x0E, 0x11, 0x01, 0x02, 0x04, 0x08, 0x1F },
['3'] = { 0x1E, 0x01, 0x01, 0x0E, 0x01, 0x01, 0x1E },
['4'] = { 0x02, 0x06, 0x0A, 0x12, 0x1F, 0x02, 0x02 },
['5'] = { 0x1F, 0x10, 0x10, 0x1E, 0x01, 0x01, 0x1E },
['6'] = { 0x0E, 0x10, 0x10, 0x1E, 0x11, 0x11, 0x0E },
['7'] = { 0x1F, 0x01, 0x02, 0x04, 0x08, 0x08, 0x08 },
['8'] = { 0x0E, 0x11, 0x11, 0x0E, 0x11, 0x11, 0x0E },
['9'] = { 0x0E, 0x11, 0x11, 0x0F, 0x01, 0x01, 0x0E },
['.'] = { 0, 0, 0, 0, 0, 0x0C, 0x0C },
[','] = { 0, 0, 0, 0, 0, 0x0C, 0x08 },
[':'] = { 0, 0x0C, 0x0C, 0, 0, 0x0C, 0x0C },
[';'] = { 0, 0x0C, 0x0C, 0, 0, 0x0C, 0x08 },
['!'] = { 0x04, 0x04, 0x04, 0x04, 0x04, 0, 0x04 },
['?'] = { 0x0E, 0x11, 0x01, 0x02, 0x04, 0, 0x04 },
['-'] = { 0, 0, 0, 0x1F, 0, 0, 0 },
['_'] = { 0, 0, 0, 0, 0, 0, 0x1F },
['+'] = { 0, 0x04, 0x04, 0x1F, 0x04, 0x04, 0 },
['='] = { 0, 0x1F, 0, 0, 0x1F, 0, 0 },
['/'] = { 0x01, 0x01, 0x02, 0x04, 0x08, 0x10, 0x10 },
['\\'] = { 0x10, 0x10, 0x08, 0x04, 0x02, 0x01, 0x01 },
['('] = { 0x02, 0x04, 0x08, 0x08, 0x08, 0x04, 0x02 },
[')'] = { 0x08, 0x04, 0x02, 0x02, 0x02, 0x04, 0x08 },
['['] = { 0x0E, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0E },
[']'] = { 0x0E, 0x02, 0x02, 0x02, 0x02, 0x02, 0x0E },
['<'] = { 0x02, 0x04, 0x08, 0x10, 0x08, 0x04, 0x02 },
['>'] = { 0x08, 0x04, 0x02, 0x01, 0x02, 0x04, 0x08 },
['*'] = { 0, 0x15, 0x0E, 0x1F, 0x0E, 0x15, 0 },
['#'] = { 0x0A, 0x0A, 0x1F, 0x0A, 0x1F, 0x0A, 0x0A },
['%'] = { 0x19, 0x19, 0x02, 0x04, 0x08, 0x13, 0x13 },
['@'] = { 0x0E, 0x11, 0x17, 0x15, 0x17, 0x10, 0x0F }
};
/**
* put a char 'c' on 'x' and 'y' in the framebuffer
* with a foreground color of 'color'
*/
void
put_char(
char c,
uint32_t x,
uint32_t y,
uint32_t size,
uint32_t fg_color,
uint32_t bg_color
) {
// convert lowercase letters to uppercase
if (c >= 'a' && c <= 'z') {
c -= 'a' - 'A';
}
// avoid indexing outside font[128]
if ((unsigned char)c >= 128) {
c = '?';
}
for (uint32_t row = 0; row < FONT_ROWS; row++) {
uint8_t bits = font[(unsigned char)c][row];
for (uint32_t col = 0; col < FONT_COLS; col++) {
uint32_t color =
bits & (1u << (FONT_COLS - 1 - col))
? fg_color : bg_color;
put_rect(
x + col * size,
y + row * size,
size,
size,
color
);
}
}
}
void
put_string(
const char *text,
uint32_t x,
uint32_t y,
uint32_t size,
uint32_t spacing,
uint32_t line_spacing,
uint32_t fg_color,
uint32_t bg_color
) {
uint32_t start_x = x;
while (*text) {
if (*text == '\n') {
x = start_x;
y += (FONT_ROWS + line_spacing) * size;
} else {
put_char(*text, x, y, size, fg_color, bg_color);
x += (FONT_COLS + spacing) * size;
}
text++;
}
}