diff options
| author | Franklin Wei <frankhwei536@gmail.com> | 2015-02-07 19:03:47 -0500 |
|---|---|---|
| committer | Franklin Wei <frankhwei536@gmail.com> | 2015-02-07 19:03:47 -0500 |
| commit | 0dc446980d8ede518a356ab2c2f165cb08ce444a (patch) | |
| tree | d9fc8938c1d930f8ece0dd5746601eca5b3089bc /drivers/gfx.c | |
| parent | 2be70c3b7c3cb806614318858090c039bdfd4fc5 (diff) | |
| download | kappa-0dc446980d8ede518a356ab2c2f165cb08ce444a.zip kappa-0dc446980d8ede518a356ab2c2f165cb08ce444a.tar.gz kappa-0dc446980d8ede518a356ab2c2f165cb08ce444a.tar.bz2 kappa-0dc446980d8ede518a356ab2c2f165cb08ce444a.tar.xz | |
implement text in graphics mode
Diffstat (limited to 'drivers/gfx.c')
| -rw-r--r-- | drivers/gfx.c | 78 |
1 files changed, 76 insertions, 2 deletions
diff --git a/drivers/gfx.c b/drivers/gfx.c index 538dadb..38a6591 100644 --- a/drivers/gfx.c +++ b/drivers/gfx.c @@ -1,5 +1,9 @@ +#include <stdbool.h> #include <stddef.h> +#include <stdio.h> #include <stdlib.h> +#include <string.h> +#include "gfx_font.h" #include "log.h" #include "multiboot.h" #include "panic.h" @@ -8,6 +12,7 @@ static uint8_t *framebuffer = NULL; static uint16_t fb_width; static uint16_t fb_height; + /* this is BYTES per pixel */ static uint8_t fb_bpp; @@ -30,13 +35,82 @@ void gfx_clear(uint32_t col) } } -void gfx_init(struct vbe_info_t *vbe_mode_info) +void gfx_drawchar(int x, int y, char c, uint32_t fg, uint32_t bg) +{ + int stride = fb_bpp * fb_width; + uint8_t *line_addr = framebuffer + (x * fb_bpp) + (y * fb_width * fb_bpp); + for(int i = y; i < y + FONT_HEIGHT; ++i) + { + uint32_t line_buf[8] = {bg}; + uint8_t mask = 0x80; + for(int j = 0; j < 8; ++j, mask >>= 1) + { + if(gfx_font[(int)c][i] & mask) + line_buf[j] = fg; + } + memcpy(line_addr, line_buf, sizeof(line_buf)); + line_addr += stride; + } +} + +static int cursor_x, cursor_y; +static uint32_t fgcol, bgcol; + +void gfx_putchar(char ch) +{ + if(ch != '\n') + { + gfx_drawchar(cursor_x, cursor_y, ch, fgcol, bgcol); + cursor_x += FONT_WIDTH; + if(cursor_x >= fb_width) + { + cursor_x = 0; + cursor_y += FONT_HEIGHT; + if(cursor_y >= fb_height) + { + gfx_clear(bgcol); + cursor_y = 0; + } + } + } + else + { + cursor_x = 0; + cursor_y += FONT_HEIGHT; + if(cursor_y >= fb_height) + { + gfx_clear(bgcol); + cursor_y = 0; + } + } +} + +void gfx_puts(const char* str) +{ + while(*str) + { + gfx_putchar(*str++); + } +} + +bool gfx_init(struct vbe_info_t *vbe_mode_info) { framebuffer = (uint8_t*)vbe_mode_info->physbase; fb_width = vbe_mode_info->Xres; fb_height = vbe_mode_info->Yres; fb_bpp = vbe_mode_info->bpp / 8; if(fb_bpp != 4) - panic("BPP *MUST* be 32!!!\n"); + { + printf("WARNING: BPP != 32, falling back to text mode...\n"); + return false; + } gfx_clear(VGA_RGBPACK(0, 0, 0)); + cursor_y = 0; + cursor_x = 0; + fgcol = VGA_RGBPACK(0xff, 0xff, 0xff); + bgcol = VGA_RGBPACK(0, 0, 0); + set_putchar(gfx_putchar); + set_puts(gfx_puts); + + return true; } |