aboutsummaryrefslogtreecommitdiff
path: root/drivers/gfx.c
diff options
context:
space:
mode:
authorFranklin Wei <frankhwei536@gmail.com>2015-02-07 19:03:47 -0500
committerFranklin Wei <frankhwei536@gmail.com>2015-02-07 19:03:47 -0500
commit0dc446980d8ede518a356ab2c2f165cb08ce444a (patch)
treed9fc8938c1d930f8ece0dd5746601eca5b3089bc /drivers/gfx.c
parent2be70c3b7c3cb806614318858090c039bdfd4fc5 (diff)
downloadkappa-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.c78
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;
}