aboutsummaryrefslogtreecommitdiff
path: root/drivers/gfx.c
diff options
context:
space:
mode:
authorFranklin Wei <frankhwei536@gmail.com>2015-03-01 14:20:47 -0500
committerFranklin Wei <frankhwei536@gmail.com>2015-03-01 14:20:47 -0500
commitc7252588ebb95f97631e9470778c69afa00c35b5 (patch)
tree06d760878e18f6cddbe4305cddd4d5dfa74529f8 /drivers/gfx.c
parentb8f54e63d2b8f8007c580adf2a6034c98a0f2eaa (diff)
downloadkappa-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.c540
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;
-}