use sff font format for console printing

This commit is contained in:
uosfz 2025-07-10 18:59:06 +02:00
parent cd36929efa
commit 772b4943c5
Signed by: uosfz
SSH key fingerprint: SHA256:FlktuluyhTQg3jHZNLKwxOOC5hbfrUXM0tz3IA3lGJo
5 changed files with 71 additions and 89 deletions

View file

@ -2,7 +2,7 @@
#define KARLOS_CONSOLE_H
void console_init(void);
void console_draw(int col, int row);
void console_draw(unsigned int row, unsigned int col);
void console_scroll(void);
void console_clear(void);
void visual_putc(char c);

View file

@ -53,4 +53,4 @@ void panic(const char *file, unsigned int line, const char *msg);
#define STATIC_ASSERT(expr) _Static_assert(expr)
#endif // KARLOS_UTILITY_H
#endif

View file

@ -1,120 +1,94 @@
#include "std.h"
#include "console.h"
#include "framebuffer.h"
#include "tar.h"
#include "sff.h"
#include <bootboot.h>
extern BOOTBOOT bootboot;
/**************************
* Display text on screen *
**************************/
typedef struct {
uint32_t magic;
uint32_t version;
uint32_t headersize;
uint32_t flags;
uint32_t numglyph;
uint32_t bytesperglyph;
uint32_t height;
uint32_t width;
uint8_t glyphs;
} __attribute__((packed)) psf2_t;
extern volatile unsigned char _binary_font_psf_start;
uint32_t console_output[200 * 100];
int console_max_rows;
int console_max_cols;
typedef uint32_t unicode_char;
#define CONSOLE_MAX_ROWS 100
#define CONSOLE_MAX_COLS 200
unicode_char console_output[CONSOLE_MAX_ROWS * CONSOLE_MAX_COLS];
int console_num_rows;
int console_num_cols;
int text_cursor_x;
int text_cursor_y;
static unsigned char *font_get_glyph(char c)
{
psf2_t *font = (psf2_t*)&_binary_font_psf_start;
unsigned char *glyphArray = (unsigned char *)&_binary_font_psf_start + font->headersize;
if (c == 0) return NULL;
if (c >= font->numglyph) return NULL;
return glyphArray + c * font->bytesperglyph;
}
struct sff_file font_file;
void console_init(void)
{
psf2_t *font = (psf2_t*)&_binary_font_psf_start;
console_max_cols = bootboot.fb_width / (font->width+1);
if (console_max_cols > 200) console_max_cols = 200;
console_max_rows = bootboot.fb_height / (font->height+1);
if (console_max_rows > 100) console_max_rows = 100;
struct tar_header hd;
ASSERT(tar_get_file("font.sff", &hd));
ASSERT(sff_decode(hd.data, &font_file));
console_num_cols = fb_width() / font_file.char_width;
if (console_num_cols > CONSOLE_MAX_COLS) console_num_cols = CONSOLE_MAX_COLS;
console_num_rows = fb_height() / font_file.char_height;
if (console_num_rows > CONSOLE_MAX_ROWS) console_num_rows = CONSOLE_MAX_ROWS;
}
void console_draw(int col, int row)
{
uint8_t *fb = fb_back ? fb_back : fb_front;
psf2_t *font = (psf2_t*)&_binary_font_psf_start;
int line, mask, offs;
int bpl = (font->width + 7)/8;
int cx = col * (font->width + 1);
int cy = row * (font->height + 1);
uint32_t chr = console_output[col + row * console_max_cols];
if (chr == 0) chr = ' ';
unsigned char *glyph = font_get_glyph(chr);
offs = 4 * cx + cy * bootboot.fb_scanline;
for (int y = 0; y < font->height; y++) {
line = offs;
mask = 1 << (font->width - 1);
for (int x = 0; x < font->width; x++) {
*((uint32_t*)((uint64_t)fb+line)) = ((int)*glyph) & (mask)?0xFFFFFF:0;
mask >>= 1;
line += 4;
void console_draw(unsigned int row, unsigned int col) {
unicode_char chr = console_output[row * console_num_cols + col];
unsigned int cx = col * font_file.char_width;
unsigned int cy = row * font_file.char_height;
struct sff_glyph_offset off;
if (sff_find_glyph(&font_file, chr, &off)) {
for (unsigned int px_row = 0; px_row < font_file.char_height; px_row++) {
for (unsigned int px_col = 0; px_col < font_file.char_width; px_col++) {
unsigned int x = col * font_file.char_width + px_col;
unsigned int y = row * font_file.char_height + px_row;
uint8_t px_value = sff_get_pixel_value(&font_file, off, px_row, px_col);
uint8_t brightness = 255 * (unsigned int)px_value / 15;
fb_set_px(x, y, COLOR(brightness, brightness, brightness));
}
}
*((uint32_t*)((uint64_t)fb+line))=0;
glyph+=bpl;
offs+=bootboot.fb_scanline;
}
fb_damage(cx, cy, cx + font->width, cy + font->height);
fb_damage(RECT_XYWH(cx, cy, font_file.char_width, font_file.char_height));
}
void console_scroll(void)
{
for (int i = 0; i+1 < console_max_rows; i++) {
memcpy(&console_output[i * console_max_cols],
&console_output[(i+1) * console_max_cols],
console_max_cols * sizeof *console_output);
for (int i = 0; i < console_num_rows - 1; i++) {
memcpy(&console_output[i * console_num_cols],
&console_output[(i+1) * console_num_cols],
console_num_cols * sizeof *console_output);
}
memset(&console_output[(console_max_rows-1) * console_max_cols], 0,
console_max_cols * sizeof *console_output);
memset(&console_output[(console_num_rows-1) * console_num_cols], 0,
console_num_cols * sizeof *console_output);
text_cursor_y--;
for (int r = 0; r < console_max_rows; r++) {
for (int c = 0; c < console_max_cols; c++) {
console_draw(c, r);
for (int r = 0; r < console_num_rows; r++) {
for (int c = 0; c < console_num_cols; c++) {
console_draw(r, c);
}
}
fb_damage(0, 0, bootboot.fb_width, bootboot.fb_height);
fb_damage(RECT(0, 0, fb_width(), fb_height()));
fb_refresh();
}
void console_clear(void)
{
memset(console_output, 0, console_max_rows * console_max_cols * sizeof *console_output);
memset(console_output, 0, console_num_rows * console_num_cols * sizeof *console_output);
text_cursor_x = 0;
text_cursor_y = 0;
uint8_t *fb = fb_back ? fb_back : fb_front;
memset(fb, 0, bootboot.fb_height * bootboot.fb_scanline);
fb_damage(0, 0, bootboot.fb_width, bootboot.fb_height);
// TODO offer more efficient frame buffer interface for this
struct color black = COLOR(0, 0, 0);
for (unsigned int y = 0; y < fb_height(); y++) {
for (unsigned int x = 0; x < fb_width(); x++) {
fb_set_px(x, y, black);
}
}
fb_damage(RECT(0, 0, fb_width(), fb_height()));
fb_refresh();
}
@ -130,19 +104,19 @@ void visual_putc(char c)
if (c == '\n') {
text_cursor_y++;
if (text_cursor_y >= console_max_rows) {
//console_scroll();
console_clear();
if (text_cursor_y >= console_num_rows) {
console_scroll();
// console_clear();
}
return;
}
text_cursor_x++;
if (col >= console_max_cols) return;
if (row >= console_max_rows) return;
if (col >= console_num_cols) return;
if (row >= console_num_rows) return;
console_output[col + row * console_max_cols] = c;
console_draw(col, row);
console_output[row * console_num_cols + col] = c;
console_draw(row, col);
fb_refresh();
}

View file

@ -78,6 +78,14 @@ void _start() {
fb_init();
console_clear();
for (unsigned int y = 0; y < fb_height(); y++) {
fb_set_px(fb_width()/2, y, COLOR(255, 0, 0));
}
// fb_damage(RECT_XYWH(0, 0, fb_width(), fb_height()));
// fb_damage(RECT(0, 20, fb_width(), fb_height() - 20));
fb_damage(RECT_XYWH(fb_width()/2, 0, 1, fb_height()));
fb_refresh();
printf("LAPIC ID: %d\n", cpu_get_core_id());
__asm__("sti");

View file

@ -72,8 +72,8 @@ static unsigned int current_buffer_position = 0;
static void linebuf_flush(void) {
for (unsigned int i = 0; i < current_buffer_position; i++) {
serial_write_char(linebuf[i]);
extern void visual_putc(char c);
visual_putc(linebuf[i]);
// extern void visual_putc(char c);
// visual_putc(linebuf[i]);
}
current_buffer_position = 0;
}