#include "ctype.h" #include "debug.h" #include "font.h" #include "fonts/eating_pasta_regular_13.h" #include "fonts/minecraft_medium_13.h" #include "icons/image.h" #include "kprintf.h" #include "shell.h" #include "string.h" #include "sys/io.h" #include "terminal.h" #include "vbe.h" #include #include #include static struct screen screens[TERM_COUNT]; struct screen *screen = &screens[0]; struct font *current_font = eating_pasta_regular_13_font; void terminal_initialize(void) { for (int i = 0; i < TERM_COUNT; i++) { screens[i].row = 0; screens[i].column = 0; screens[i].default_color = 0xffffff; screens[i].fg_color = screens[i].default_color; /* memcpy(screens[i].buffer, TERM_BUF, sizeof(screen->buffer)); */ } } void terminal_set_screen(int pos) { // TODO /* memcpy(screen->buffer, TERM_BUF, sizeof(screen->buffer)); */ /* screen = &screens[pos]; */ /* memcpy(TERM_BUF, screen->buffer, sizeof(screen->buffer)); */ /* update_cursor(); */ /* if (TERM_BUF[0] == vga_entry(' ', VGA_COLOR_WHITE)) */ /* kprintf(PROMPT); */ } void terminal_set_bg_color(uint32_t bg_color) { screen->bg_color = bg_color; } void terminal_set_fg_color(uint32_t fg_color) { screen->fg_color = screen->fg_color; } void terminal_set_color(uint32_t fg_color, uint32_t bg_color) { screen->fg_color = fg_color; screen->bg_color = bg_color; } void terminal_set_default_fg_color(uint32_t fg_color) { screen->default_color = fg_color; } uint32_t terminal_get_default_color(void) { return screen->default_color; } uint8_t terminal_get_char(int x, int y) { return screen->buffer[y * VGA_WIDTH + x]; } void terminal_putentryat(struct font node, uint32_t fg_color, uint32_t bg_color, size_t x, size_t y) { if (node.width == 1 && node.height == 1) { return; } char *glyph = node.bitmap; for (size_t cy = 0; cy < node.height; cy++) { for (size_t cx = 0; cx < node.width; cx++) { if (glyph[cy * node.width + cx] == '#') put_pixel(fg_color, x + cx, y + cy); /* put_pixel((glyph[cy * node.width + * cx] == '#') ? fg_color */ /* : bg_color, */ /* x + cx, y + cy); */ /* else if (bg_color) */ /* put_pixel(bg_color, x + cx, y + cy); */ } } } static struct font get_font_node(int c) { return current_font[c]; } static void terminal_scroll(void) { screen->row--; draw_icon(0, 0, &image_icon); for (size_t i = 0; i < VGA_WIDTH * (VGA_HEIGHT - 1); i++) { const uint32_t x = (i % VGA_WIDTH) * FONT_SIZE; const uint32_t y = (i / VGA_WIDTH) * FONT_SIZE; screen->buffer[i] = screen->buffer[i + VGA_WIDTH]; terminal_putentryat(get_font_node(screen->buffer[i]), screen->fg_color, screen->bg_color, x, y); } /* for (size_t i = 0; i < VGA_WIDTH; i++) */ /* terminal_putentryat(get_font_node(' '), 0, 0, i * FONT_SIZE, */ /* (VGA_HEIGHT - 1) * FONT_SIZE); */ } static void terminal_new_line(void) { screen->column = 0; if (++screen->row == VGA_HEIGHT - 1) terminal_scroll(); } void terminal_change_default_color(uint32_t color) { // TODO /* terminal_set_color(color); */ /* for (size_t y = 0; y < VGA_HEIGHT; y++) { */ /* for (size_t x = 0; x < VGA_WIDTH; x++) { */ /* const size_t index = y * VGA_WIDTH + x; */ /* uint8_t entry_color = * get_entry_color(TERM_BUF[index]); */ /* TERM_BUF[index] = vga_entry( */ /* TERM_BUF[index], */ /* entry_color == screen->default_color * ? color */ /* : * entry_color); */ /* } */ /* } */ /* memcpy(screen->buffer, TERM_BUF, * sizeof(screen->buffer)); */ /* screen->default_color = color; */ /* screen->color = color; */ } void terminal_change_default_fg_color(uint32_t fg_color) { terminal_set_fg_color(fg_color); terminal_change_default_color(screen->fg_color); } void terminal_clear(void) { // TODO /* for (size_t y = 0; y < VGA_HEIGHT; y++) { */ /* for (size_t x = 0; x < VGA_WIDTH; x++) { */ /* const size_t index = y * VGA_WIDTH + x; */ /* TERM_BUF[index] = vga_entry(' ', * screen->color); */ /* } */ /* } */ /* memcpy(screen->buffer, TERM_BUF, * sizeof(screen->buffer)); */ /* screen->column = 0; */ /* screen->row = 0; */ } int terminal_putchar(char c) { if (c == '\r') screen->column = 0; else if (c == '\n') terminal_new_line(); if (!isprint(c)) return 1; /* if (c == ' ') { */ /* for (size_t cy = 0; cy < 13; cy++) */ /* for (size_t cx = 0; cx < 13; cx++) */ /* put_pixel(0, screen->column + cx, */ /* screen->row + cy); */ /* } else { */ screen->buffer[screen->column + screen->row * VGA_WIDTH] = c; terminal_putentryat(get_font_node(c), screen->fg_color, screen->bg_color, screen->column * FONT_SIZE, screen->row * FONT_SIZE); if (++screen->column == VGA_WIDTH) terminal_new_line(); /* } */ return 1; } int terminal_write(const char *data, size_t size) { size_t i; for (i = 0; i < size; i++) terminal_putchar(data[i]); return (int)i; } int terminal_writestring(const char *data) { size_t len = strlen(data); terminal_write(data, len); return len; } void update_cursor(void) { /* uint16_t pos = screen->row * VGA_WIDTH + * screen->column; */ /* outb(0x3D4, 0x0F); */ /* outb(0x3D5, pos & 0xFF); */ /* outb(0x3D4, 0x0E); */ /* outb(0x3D5, (pos >> 8) & 0xFF); */ } void move_cursor(int direction) { switch (direction) { case LEFT: if (screen->column) { screen->column--; } else if (screen->row) { screen->column = VGA_WIDTH - 1; screen->row--; } break; case RIGHT: if (screen->column < VGA_WIDTH - 1) { screen->column++; } else if (screen->row < VGA_HEIGHT - 1) { screen->column = 0; screen->row++; } else { terminal_new_line(); } break; case UP: break; case DOWN: break; default: break; } update_cursor(); } void set_color_level(int level) { int color_translation[] = { VGA_COLOR_WHITE, VGA_COLOR_RED, VGA_COLOR_RED, VGA_COLOR_MAGENTA, VGA_COLOR_LIGHT_YELLOW, VGA_COLOR_LIGHT_YELLOW, VGA_COLOR_LIGHT_BLUE, VGA_COLOR_GREEN, VGA_COLOR_LIGHT_GREY}; if (level == 0) { terminal_set_color(screen->default_color, 0); return; } terminal_set_fg_color(color_translation[level]); }