/* Copyright (C) 2012, Aaron Lindsay This file is part of Aedrix. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #include #include #include char *console_buffer, *cb_first_line; struct fb *console_framebuffer; struct font *console_font; unsigned int chars_per_line, lines; unsigned int curr_char, curr_line; void console_char_to_fb(char c, unsigned int chr, unsigned int line) { unsigned int x, y; unsigned int cx, cy, bit = 0; char *font_char = &console_font->data[console_font->bytes_per_char * (c - console_font->ascii_offset)]; x = chr * console_font->width; y = line * console_font->height; for (cy = 0; cy < console_font->height; cy++) { for (cx = 0; cx < console_font->width; cx++) { unsigned char on = font_char[bit / 8] & (1 << (bit % 8)); if (on) fb_write_pixel(console_framebuffer, x + cx, y + cy, 0xff, 0xff, 0xff); else fb_write_pixel(console_framebuffer, x + cx, y + cy, 0x00, 0x00, 0x00); bit++; } } } void console_redraw_fb() { unsigned int cc, cl = 0; char *c; if (!console_framebuffer) return; for (c = cb_first_line; c < console_buffer + chars_per_line * lines; c += chars_per_line) { char *d; cc = 0; for (d = c; d < c + chars_per_line; d++) console_char_to_fb(*d, cc++, cl); cl++; } for (c = console_buffer; c < cb_first_line; c += chars_per_line) { char *d; cc = 0; for (d = c; d < c + chars_per_line; d++) console_char_to_fb(*d, cc++, cl); cl++; } } void console_buffer_clear() { char *c; for (c = console_buffer; c < console_buffer + chars_per_line * lines; c++) *c = ' '; curr_char = 0; curr_line = 0; } int console_init(struct fb *f) { console_framebuffer = f; console_font = font_get(); lines = console_framebuffer->height / console_font->height; chars_per_line = console_framebuffer->width / console_font->width; curr_line = 0; curr_char = 0; if (!(console_buffer = kmalloc(sizeof(char) * chars_per_line * lines))) { print("Error: Failed to allocate memory for console buffer\n"); return -1; } cb_first_line = console_buffer; console_buffer_clear(); console_redraw_fb(); return 0; } void console_newline() { char *c; curr_line++; curr_char = 0; if (curr_line == lines) { char *console_buffer_end = console_buffer + chars_per_line * lines; //empty the current first line, since it will wrap around to the bottom for (c = cb_first_line; c < cb_first_line + chars_per_line; c++) *c = ' '; cb_first_line += chars_per_line; if (cb_first_line >= console_buffer_end) cb_first_line = console_buffer; curr_line = lines - 1; console_redraw_fb(); } } int console_putc(char c) { char *console_buffer_end = console_buffer + chars_per_line * lines; char *write_char_at; switch (c) { case '\n': console_newline(); return 0; case '\r': curr_char = 0; return 0; default: break; } if (curr_char + 1 > chars_per_line) console_newline(); write_char_at = cb_first_line + chars_per_line * curr_line + curr_char; if (write_char_at >= console_buffer_end) write_char_at -= chars_per_line * lines; *write_char_at = c; console_char_to_fb(c, curr_char++, curr_line); return 0; }