diff options
| author | Franklin Wei <frankhwei536@gmail.com> | 2015-03-01 14:20:47 -0500 |
|---|---|---|
| committer | Franklin Wei <frankhwei536@gmail.com> | 2015-03-01 14:20:47 -0500 |
| commit | c7252588ebb95f97631e9470778c69afa00c35b5 (patch) | |
| tree | 06d760878e18f6cddbe4305cddd4d5dfa74529f8 /drivers/gfx.c | |
| parent | b8f54e63d2b8f8007c580adf2a6034c98a0f2eaa (diff) | |
| download | kappa-c7252588ebb95f97631e9470778c69afa00c35b5.zip kappa-c7252588ebb95f97631e9470778c69afa00c35b5.tar.gz kappa-c7252588ebb95f97631e9470778c69afa00c35b5.tar.bz2 kappa-c7252588ebb95f97631e9470778c69afa00c35b5.tar.xz | |
Huge restructure
Diffstat (limited to 'drivers/gfx.c')
| -rw-r--r-- | drivers/gfx.c | 540 |
1 files changed, 0 insertions, 540 deletions
diff --git a/drivers/gfx.c b/drivers/gfx.c deleted file mode 100644 index 2f4864b..0000000 --- a/drivers/gfx.c +++ /dev/null @@ -1,540 +0,0 @@ -#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 "paging.h" -#include "panic.h" -#include "gfx.h" - -uint8_t *real_framebuffer = NULL; -uint8_t *temp_framebuffer = NULL; -uint8_t *framebuffer = NULL; -bool double_buffer = false; -uint16_t fb_width; -uint16_t fb_height; - -/* this is BYTES per pixel */ -uint8_t fb_bpp; -uint16_t fb_stride; -/* fb_stride / 4 */ -uint16_t fb_stride32; -const uint8_t *gfx_bpp = &fb_bpp; - -const uint16_t *gfx_width = &fb_width; -const uint16_t *gfx_height = &fb_height; - -static int cursor_x, cursor_y; -uint32_t _gfx_fgcol, _gfx_bgcol; - -void (*gfx_clear)(void); -void (*gfx_drawpixel)(int x, int y); -void (*gfx_hline)(int x1, int x2, int y); -void (*gfx_vline)(int y1, int y2, int x); - -void gfx_set_background(uint32_t col) -{ - _gfx_bgcol = col; -} - -uint32_t gfx_get_background(void) -{ - return _gfx_bgcol; -} - -void gfx_set_foreground(uint32_t col) -{ - _gfx_fgcol = col; -} - -uint32_t gfx_get_foreground(void) -{ - return _gfx_fgcol; -} - -/* assembly */ -void gfx_drawpixel_32bpp_checked(int x, int y) -{ - if(0 <= x && x < fb_width && - 0 <= y && y < fb_height) - ((uint32_t*)framebuffer)[y * fb_stride32 + x] = _gfx_fgcol; - else - panic("pixel OOB!\n"); -} - -/* implemented in assembly now */ -/* -void gfx_clear(uint32_t col) -{ - uint8_t *p = framebuffer; - uint8_t *stop = framebuffer + fb_width * fb_height * fb_bpp; - while(p < stop) - { - *(uint32_t*)p = col; - p += fb_bpp; - } -} -*/ - -void gfx_clear_unpacked(void) -{ - uint8_t *fb = framebuffer; - const uint32_t bg = _gfx_bgcol; - - const uint16_t padding = fb_stride - (fb_bpp * fb_width); - - for(int y = 0; y < fb_height; ++y) - { - for(int x = 0; x < fb_width; ++x) - { - *(uint32_t*)fb++ = bg; - } - fb += padding; - } -} - -void gfx_reset(void) -{ - _gfx_fgcol = VGA_RGBPACK(0xff, 0xff, 0xff); - _gfx_bgcol = VGA_RGBPACK(0, 0, 0); - gfx_clear(); - cursor_y = 0; - cursor_x = 0; -} - -void gfx_drawchar(int x, int y, int c) -{ - uint8_t *line_addr = framebuffer + (x * fb_bpp) + (y * fb_stride); - const uint32_t fg = _gfx_fgcol; - const uint16_t stride = fb_stride; - const uint8_t stop_y = MIN(FONT_HEIGHT, fb_height - y); - const uint8_t stop_x = MIN(FONT_WIDTH, fb_width - x); - if(c < 0 || c > 132) - return; - for(int i = 0; i < stop_y; ++i) - { - uint8_t mask_table[8] = {128, 64, 32, 16, 8, 4, 2, 1}; - for(int j = 0; j < stop_x; ++j) - { - if(gfx_font[c][i] & mask_table[j]) - ((uint32_t*)line_addr)[j] = fg; - } - line_addr += stride; - } -} - -void gfx_drawchar_bg(int x, int y, int c) -{ - uint8_t *line_addr = framebuffer + (x * fb_bpp) + (y * fb_stride); - const uint32_t fg = _gfx_fgcol; - const uint16_t stride = fb_stride; - const uint8_t stop_y = MIN(FONT_HEIGHT, fb_height - y); - const uint8_t stop_x = MIN(FONT_WIDTH, fb_width - x); - if(c < 0 || c > 132) - return; - for(int i = 0; i < stop_y; ++i) - { - uint8_t mask_table[8] = {128, 64, 32, 16, 8, 4, 2, 1}; - for(int j = 0; j < stop_x; ++j) - { - if(gfx_font[c][i] & mask_table[j]) - ((uint32_t*)line_addr)[j] = fg; - else - ((uint32_t*)line_addr)[j] = _gfx_bgcol; - } - line_addr += stride; - } -} - -void gfx_putchar(int ch) -{ - if(ch != '\n' && ch != '\b') - { - gfx_drawchar(cursor_x, cursor_y, ch); - cursor_x += FONT_WIDTH; - if(cursor_x >= fb_width) - { - cursor_x = 0; - cursor_y += FONT_HEIGHT; - if(cursor_y >= fb_height) - { - gfx_clear(); - cursor_y = 0; - } - } - } - else if(ch == '\n') - { - cursor_x = 0; - cursor_y += FONT_HEIGHT; - if(cursor_y >= fb_height) - { - gfx_clear(); - cursor_y = 0; - } - } - else if(ch == '\b') - { - int temp_x = cursor_x - FONT_WIDTH; - if(temp_x >= 0) - cursor_x = temp_x; - gfx_drawchar_bg(cursor_x, cursor_y, ' '); - } -} - -void gfx_puts(const char* str) -{ - while(*str) - { - gfx_putchar(*str++); - } -} - -/* implemented in assembly now */ -void gfx_hline_checked(int x1, int x2, int y) -{ - /* make sure x1 is to the left of x2 */ - if(x2 < x1) - { - int temp = x1; - x1 = x2; - x2 = temp; - } - - x1 = MAX(0, x1); - x2 = MIN(x2, fb_width); - - if(0 <= y && y < fb_height) - { - - uint8_t *base = framebuffer + y * fb_stride; - - uint8_t *dest = base + x1 * fb_bpp; - uint8_t *stop = base + x2 * fb_bpp; - const uint32_t col = _gfx_fgcol; - while(dest < stop) - { - *(uint32_t*)dest = col; - dest += fb_bpp; - } - } -} - -void gfx_vline_checked(int y1, int y2, int x) -{ - /* make sure y1 is above y2 */ - if(y2 < y1) - { - int temp = y1; - y1 = y2; - y2 = temp; - } - - y1 = MAX(0, y1); - y2 = MIN(y2, fb_height); - - if(0 <= x && x < fb_width) - { - uint8_t *dest = framebuffer + y1 * fb_stride + x * fb_bpp; - uint8_t *stop = framebuffer + y2 * fb_stride + x * fb_bpp; - const uint32_t col = _gfx_fgcol; - const uint16_t stride = fb_stride; - while(dest < stop) - { - *(uint32_t*)dest = col; - dest += stride; - } - } -} - -void gfx_fillrect(int x, int y, int w, int h) -{ - for(int i = 0; i < h; ++i) - { - gfx_hline(x, x + w, y + i); - } -} - -void gfx_drawline(int x1, int y1, int x2, int y2) -{ - int dx = abs(x2 - x1); - int sx = x1 < x2 ? 1 : -1; - int dy = -abs(y2 - y1); - int sy = y1 < y2 ? 1 : -1; - int err = dx + dy; - int e2; /* error value e_xy */ - - while(1) - { - gfx_drawpixel(x1, y1); - if (x1 == x2 && y1 == y2) - break; - e2 = err << 1; - if (e2 >= dy) - { - err += dy; - x1 += sx; - } - if (e2 <= dx) - { - err += dx; - y1 += sy; - } - } -} - -void gfx_drawcircle(int cx, int cy, int r) -{ - int d = 3 - (r * 2); - int x = 0; - int y = r; - while(x <= y) - { - gfx_drawpixel(cx + x, cy + y); - gfx_drawpixel(cx - x, cy + y); - gfx_drawpixel(cx + x, cy - y); - gfx_drawpixel(cx - x, cy - y); - gfx_drawpixel(cx + y, cy + x); - gfx_drawpixel(cx - y, cy + x); - gfx_drawpixel(cx + y, cy - x); - gfx_drawpixel(cx - y, cy - x); - if(d < 0) - { - d += (x * 4) + 6; - } - else - { - d += ((x - y) * 4) + 10; - --y; - } - ++x; - } -} - -void gfx_fillcircle(int cx, int cy, int r) -{ - int d = 3 - (r * 2); - int x = 0; - int y = r; - while(x <= y) - { - gfx_hline(cx - x, cx + x, cy + y); - gfx_hline(cx - x, cx + x, cy - y); - gfx_hline(cx - y, cx + y, cy + x); - gfx_hline(cx - y, cx + y, cy - x); - if(d < 0) - { - d += (x * 4) + 6; - } - else - { - d += ((x - y) * 4) + 10; - --y; - } - ++x; - } -} - -/* these next two functions were taken directly from the Rockbox project's XLCD - * library. - * Copyright (C) 2005 Jens Arnold */ - -/* sort the given coordinates by increasing x value */ -static void sort_points_by_increasing_y(int* y1, int* x1, - int* y2, int* x2, - int* y3, int* x3) -{ - int x, y; - if (*x1 > *x3) - { - if (*x2 < *x3) /* x2 < x3 < x1 */ - { - x = *x1; *x1 = *x2; *x2 = *x3; *x3 = x; - y = *y1; *y1 = *y2; *y2 = *y3; *y3 = y; - } - else if (*x2 > *x1) /* x3 < x1 < x2 */ - { - x = *x1; *x1 = *x3; *x3 = *x2; *x2 = x; - y = *y1; *y1 = *y3; *y3 = *y2; *y2 = y; - } - else /* x3 <= x2 <= x1 */ - { - x = *x1; *x1 = *x3; *x3 = x; - y = *y1; *y1 = *y3; *y3 = y; - } - } - else - { - if (*x2 < *x1) /* x2 < x1 <= x3 */ - { - x = *x1; *x1 = *x2; *x2 = x; - y = *y1; *y1 = *y2; *y2 = y; - } - else if (*x2 > *x3) /* x1 <= x3 < x2 */ - { - x = *x2; *x2 = *x3; *x3 = x; - y = *y2; *y2 = *y3; *y3 = y; - } - /* else already sorted */ - } -} - -/* draw a filled triangle, using horizontal lines for speed */ -void gfx_filltriangle(int x1, int y1, - int x2, int y2, - int x3, int y3) -{ - long fp_x1, fp_x2, fp_dx1, fp_dx2; - int y; - sort_points_by_increasing_y(&x1, &y1, &x2, &y2, &x3, &y3); - - if (y1 < y3) /* draw */ - { - fp_dx1 = ((x3 - x1) << 16) / (y3 - y1); - fp_x1 = (x1 << 16) + (1<<15) + (fp_dx1 >> 1); - - if (y1 < y2) /* first part */ - { - fp_dx2 = ((x2 - x1) << 16) / (y2 - y1); - fp_x2 = (x1 << 16) + (1<<15) + (fp_dx2 >> 1); - for (y = y1; y < y2; y++) - { - gfx_hline(fp_x1 >> 16, fp_x2 >> 16, y); - fp_x1 += fp_dx1; - fp_x2 += fp_dx2; - } - } - if (y2 < y3) /* second part */ - { - fp_dx2 = ((x3 - x2) << 16) / (y3 - y2); - fp_x2 = (x2 << 16) + (1<<15) + (fp_dx2 >> 1); - for (y = y2; y < y3; y++) - { - gfx_hline(fp_x1 >> 16, fp_x2 >> 16, y); - fp_x1 += fp_dx1; - fp_x2 += fp_dx2; - } - } - } -} - -static void gfx_bitmap32(int x, int y, const struct bitmap_t *bmp) -{ - /* SLOOW */ - uint8_t *data = bmp->data; - for(unsigned int i = y; i < y + bmp->h && i < fb_height; ++i) - { - for(unsigned int j = x; j < x + bmp->w && j < fb_width; ++j) - { - uint8_t r = *data++; - uint8_t g = *data++; - uint8_t b = *data++; - gfx_set_foreground(VGA_RGBPACK(r, g, b)); - gfx_drawpixel(j, i); - } - } -} - -void gfx_bitmap(int x, int y, const struct bitmap_t *bmp) -{ - gfx_bitmap32(x, y, bmp); -} - -void gfx_drawrect(int x, int y, int w, int h) -{ - gfx_hline(MAX(0, x), MIN(x + w, fb_width), MAX(0, y)); - gfx_hline(MAX(0, x), MIN(x + w, fb_width), MIN(y + h, fb_height)); - gfx_vline(MAX(0, y), MIN(y + h, fb_height),MAX(0, x)); - gfx_vline(MAX(0, y), MIN(y + h, fb_height),MIN(x + w, fb_width)); -} - -void gfx_update(void) -{ - memcpy(real_framebuffer, framebuffer, fb_height * fb_stride); -} - -void gfx_set_doublebuffer(bool yesno) -{ - if(yesno) - framebuffer = temp_framebuffer; - else - framebuffer = real_framebuffer; -} - -bool gfx_get_doublebuffer(void) -{ - if(framebuffer == temp_framebuffer) - return true; - else - return false; -} - -void gfx_putsxy(int x, int y, const char* str) -{ - while(*str) - { - gfx_drawchar(x, y, *str); - x += FONT_WIDTH; - str++; - } -} - -void gfx_putsxy_bg(int x, int y, const char* str) -{ - while(*str) - { - gfx_drawchar_bg(x, y, *str); - x += FONT_WIDTH; - str++; - } -} - -bool gfx_init(struct vbe_info_t *vbe_mode_info) -{ - real_framebuffer = (uint8_t*)vbe_mode_info->physbase; - gfx_set_doublebuffer(false); - fb_width = vbe_mode_info->Xres; - fb_height = vbe_mode_info->Yres; - fb_bpp = vbe_mode_info->bpp / 8; - fb_stride = vbe_mode_info->pitch; - fb_stride32 = fb_stride / sizeof(uint32_t); - gfx_hline = gfx_hline_checked; - gfx_vline = gfx_vline_checked; - temp_framebuffer = malloc(fb_height * fb_stride); - if(fb_bpp != 4) - { - printf("WARNING: BPP != 32, falling back to text mode...\n"); - return false; - } - else - { - extern void gfx_drawpixel_32bpp(int, int); - gfx_drawpixel = &gfx_drawpixel_32bpp; - } - - set_putchar(gfx_putchar); - set_puts(gfx_puts); - - /* A bit of fragile code here... don't call gfx_reset() before setting gfx_clear! */ - - if(fb_stride != fb_bpp * fb_width) - { - gfx_clear = &gfx_clear_unpacked; - gfx_reset(); - printf("WARNING: Internal framebuffer padding detected, support is experimental.\n"); - } - else - { - /* assembly */ - extern void gfx_clear_packed(void); - gfx_clear = &gfx_clear_packed; - gfx_reset(); - } - - printf("Real FB addr: 0x%x\n", (uint32_t)real_framebuffer); - - return true; -} |