diff options
| author | Franklin Wei <frankhwei536@gmail.com> | 2015-02-17 15:33:03 -0500 |
|---|---|---|
| committer | Franklin Wei <frankhwei536@gmail.com> | 2015-02-17 15:33:03 -0500 |
| commit | 6030b176c2819c83c625f257ad7e8632a8245ed9 (patch) | |
| tree | fd98417c4f40a3bc8479a5900920a0ccd40fedd6 /drivers | |
| parent | ef4cc242dc8ad04320d19af22931fcbdbf670c13 (diff) | |
| download | kappa-6030b176c2819c83c625f257ad7e8632a8245ed9.zip kappa-6030b176c2819c83c625f257ad7e8632a8245ed9.tar.gz kappa-6030b176c2819c83c625f257ad7e8632a8245ed9.tar.bz2 kappa-6030b176c2819c83c625f257ad7e8632a8245ed9.tar.xz | |
Emulate the Rockbox plugin API, ported xracer
Tons of changes
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/gfx-as.S | 11 | ||||
| -rw-r--r-- | drivers/gfx.c | 218 | ||||
| -rw-r--r-- | drivers/gfx_font.c | 10 | ||||
| -rw-r--r-- | drivers/include/gfx.h | 26 | ||||
| -rw-r--r-- | drivers/ps2.c | 3 |
5 files changed, 235 insertions, 33 deletions
diff --git a/drivers/gfx-as.S b/drivers/gfx-as.S index 675a6d5..a58fa12 100644 --- a/drivers/gfx-as.S +++ b/drivers/gfx-as.S @@ -25,8 +25,10 @@ gfx_clear_packed: popl %ebx ret - .global gfx_hline -gfx_hline: + .global gfx_hline_fast + +gfx_hline_fast: + int $0x80 pushl %ebx movl 8(%esp), %eax movl 12(%esp), %ecx @@ -54,8 +56,9 @@ gfx_hline: popl %ebx ret - .global gfx_vline -gfx_vline: + .global gfx_vline_fast + +gfx_vline_fast: pushl %esi pushl %ebx movl 12(%esp), %eax diff --git a/drivers/gfx.c b/drivers/gfx.c index 7c56800..028a5e5 100644 --- a/drivers/gfx.c +++ b/drivers/gfx.c @@ -9,7 +9,10 @@ #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; @@ -28,6 +31,8 @@ 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) { @@ -58,6 +63,7 @@ void gfx_drawpixel_32bpp_checked(int x, int y) else panic("pixel OOB!\n"); } + /* implemented in assembly now */ /* void gfx_clear(uint32_t col) @@ -195,8 +201,7 @@ void gfx_puts(const char* str) } /* implemented in assembly now */ -#if 0 -void gfx_hline(int x1, int x2, int y) +void gfx_hline_checked(int x1, int x2, int y) { /* make sure x1 is to the left of x2 */ if(x2 < x1) @@ -206,19 +211,26 @@ void gfx_hline(int x1, int x2, int y) x2 = temp; } - uint8_t *base = framebuffer + y * fb_stride; + x1 = MAX(0, x1); + x2 = MIN(x2, fb_width); - uint8_t *dest = base + x1 * fb_bpp; - uint8_t *stop = base + x2 * fb_bpp; - const uint32_t col = _gfx_fgcol; - while(dest < stop) + if(0 <= y && y < fb_height) { - *(uint32_t*)dest = col; - dest += fb_bpp; + + 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(int y1, int y2, int x) +void gfx_vline_checked(int y1, int y2, int x) { /* make sure y1 is above y2 */ if(y2 < y1) @@ -228,17 +240,22 @@ void gfx_vline(int y1, int y2, int x) y2 = temp; } - 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) + y1 = MAX(0, y1); + y2 = MIN(y2, fb_height); + + if(0 <= x && x < fb_width) { - *(uint32_t*)dest = col; - dest += stride; + 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; + } } } -#endif void gfx_fillrect(int x, int y, int w, int h) { @@ -328,15 +345,172 @@ void gfx_fillcircle(int cx, int cy, int r) } } +/* 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) { - framebuffer = (uint8_t*)vbe_mode_info->physbase; + 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 / 4; + 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"); @@ -344,8 +518,8 @@ bool gfx_init(struct vbe_info_t *vbe_mode_info) } else { - //extern void gfx_drawpixel_32bpp(int, int); - gfx_drawpixel = &gfx_drawpixel_32bpp_checked; + extern void gfx_drawpixel_32bpp(int, int); + gfx_drawpixel = &gfx_drawpixel_32bpp; } set_putchar(gfx_putchar); diff --git a/drivers/gfx_font.c b/drivers/gfx_font.c index 4515b31..6669931 100644 --- a/drivers/gfx_font.c +++ b/drivers/gfx_font.c @@ -1719,10 +1719,10 @@ const uint8_t gfx_font[][12] = { b(11111000), b(11111100), b(11111110), - b(11111111), /* 8 */ - b(11111000), - b(11011000), - b(10001100), - b(00000110) /* 12 */ + b(11100000), /* 8 */ + b(11000000), + b(10000000), + b(00000000), + b(00000000) /* 12 */ }, }; diff --git a/drivers/include/gfx.h b/drivers/include/gfx.h index 2abc172..5e97100 100644 --- a/drivers/include/gfx.h +++ b/drivers/include/gfx.h @@ -62,9 +62,9 @@ void gfx_set_background(uint32_t); uint32_t gfx_get_background(void); -void gfx_hline(int x1, int x2, int y); +void (*gfx_hline)(int x1, int x2, int y); -void gfx_vline(int y1, int y2, int x); +void (*gfx_vline)(int y1, int y2, int x); void gfx_fillrect(int x1, int y1, int w, int h); @@ -75,9 +75,31 @@ void gfx_drawcircle(int cx, int cy, int rad); void gfx_fillcircle(int cx, int cy, int rad); +void gfx_filltriangle(int x1, int y1, int x2, int y2, int x3, int y3); + extern const uint16_t *gfx_width, *gfx_height; /* this is _BYTES_ per pixel, NOT BITS per pixel! */ extern const uint8_t *gfx_bpp; +struct bitmap_t { + unsigned int w, h; + unsigned int bpp; + uint8_t *data; +}; + +void gfx_bitmap(int x, int y, const struct bitmap_t*); + +void gfx_drawrect(int x, int y, int w, int h); + +void gfx_set_doublebuffer(bool); + +bool gfx_get_doublebuffer(void); + +/* don't call this wo/ double buffering! */ +void gfx_update(void); + +void gfx_putsxy(int, int, const char*); + +void gfx_putsxy_bg(int, int, const char*); #endif diff --git a/drivers/ps2.c b/drivers/ps2.c index c9ff30e..9da026d 100644 --- a/drivers/ps2.c +++ b/drivers/ps2.c @@ -4,6 +4,7 @@ #include "io.h" #include "isr.h" #include "ps2.h" +#include "ps2_keymaps.h" static void ps2_wait(void) { @@ -19,6 +20,8 @@ void ps2_set_leds(uint8_t status) outb(0x60, status); } +static uint8_t keyboard_state[16]; + static void key_handler(struct regs_t *regs) { (void) regs; |