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 #define KARLOS_CONSOLE_H
void console_init(void); 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_scroll(void);
void console_clear(void); void console_clear(void);
void visual_putc(char c); 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) #define STATIC_ASSERT(expr) _Static_assert(expr)
#endif // KARLOS_UTILITY_H #endif

View file

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

View file

@ -78,6 +78,14 @@ void _start() {
fb_init(); fb_init();
console_clear(); 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()); printf("LAPIC ID: %d\n", cpu_get_core_id());
__asm__("sti"); __asm__("sti");

View file

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