os-workshop

same materials and sample source for RV32 OS projects
git clone http://frotz.net/git/os-workshop.git
Log | Files | Refs

gfx.c (3398B)


      1 // Copyright 2022, Brian Swetland <swetland@frotz.net>
      2 // Licensed under the Apache License, Version 2.0
      3 
      4 #include <stdio.h>
      5 #include <stdarg.h>
      6 
      7 #include <gfx/gfx.h>
      8 #include <compiler.h>
      9 #include <hw/platform.h>
     10 
     11 extern uint8_t vga_rom_16[256 * 16];
     12 
     13 #define CH_ROM     vga_rom_16
     14 #define CH_WIDTH   8
     15 #define CH_HEIGHT  16
     16 
     17 // drawing routines for unknown pixfmt
     18 static uint32_t color0(gfx_surface_t *gs, uint32_t c) { return 0; }
     19 static void plot0(gfx_surface_t *gs, uint32_t x, uint32_t y, uint32_t pxl) {}
     20 static void hline0(gfx_surface_t *gs, uint32_t x0, uint32_t y, uint32_t x1, uint32_t pxl) {}
     21 static void putc0(gfx_surface_t *gs, uint32_t x, uint32_t y, uint32_t c) {}
     22 
     23 // drawing routines for 16bpp pixfmt
     24 static uint32_t color16(gfx_surface_t *gs, uint32_t c) {
     25 	return ((c >> 3) & 0x1F) |
     26 		(((c >> 10) & 0x3F) << 5) |
     27 		(((c >> 19) & 0x1F) << 11);
     28 }
     29 
     30 static void plot16(gfx_surface_t *gs, uint32_t x, uint32_t y, uint32_t pxl) {
     31 	if (unlikely((x >= gs->width) || (y >= gs->height))) {
     32 		return;
     33 	}	
     34 	((uint16_t*) (gs->pixels))[x + y * gs->stride] = pxl;
     35 }
     36  
     37 static void hline16(gfx_surface_t *gs, uint32_t x0, uint32_t y, uint32_t x1, uint32_t pxl) {
     38 	if (unlikely((x0 >= gs->width) || (y >= gs->height) || (x1 <= x0))) {
     39 		return;
     40 	}
     41 	if (unlikely((x1 > gs->width))) {
     42 		x1 = gs->width;
     43 	}
     44 	uint16_t *pixels = ((uint16_t*)gs->pixels) + x0 + y * gs->stride;
     45 	uint16_t *end = pixels + x1 - x0;
     46 	while (pixels < end) {
     47 		*pixels++ = pxl;
     48 	}
     49 }
     50 
     51 static void putc16(gfx_surface_t *gs, uint32_t x, uint32_t y, uint32_t ch) {
     52 	if (unlikely((x >= gs->width) || ((x + CH_WIDTH) > gs->width) ||
     53 		(y >= gs->height) || ((y + CH_HEIGHT) > gs->height))) {
     54 		return;
     55 	}
     56 
     57 	ch = (ch & 0xFF) * CH_HEIGHT;
     58 	uint32_t fg = gs->fgcolor;
     59 	uint32_t bg = gs->bgcolor;
     60 	uint16_t *pixels = ((uint16_t*)gs->pixels) + x + y * gs->stride;
     61 	uint32_t stride = gs->stride - CH_WIDTH;
     62 	for (y = 0; y < CH_HEIGHT; y++) {
     63 		uint32_t bits = CH_ROM[ch++];
     64 		for (x = 0; x < CH_WIDTH; x++) {
     65 			*pixels++ = (bits & 0x80) ? fg : bg;
     66 			bits <<= 1;
     67 		}
     68 		pixels += stride;
     69 	}
     70 }
     71 
     72 void gfx_init(gfx_surface_t *gs) {
     73 	switch (gs->pixfmt) {
     74 	case PIXFMT_RGB565:
     75 		gs->plot = plot16;
     76 		gs->hline = hline16;
     77 		gs->putc = putc16;
     78 		gs->color = color16;
     79 		break;
     80 	default:
     81 		gs->plot = plot0;
     82 		gs->hline = hline0;
     83 		gs->putc = putc0;
     84 		gs->color = color0;
     85 		break;
     86 	}
     87 }
     88 
     89 void gfx_init_display(gfx_surface_t *gs) {
     90 	gs->width = 640;
     91 	gs->height = 480;
     92 	gs->stride = 640;
     93 	gs->pixels = (void*) FRAMEBUFFER_BASE;
     94 	gs->pixfmt = PIXFMT_RGB565;
     95 	gfx_init(gs);
     96 	gs->fgcolor = gs->color(gs, C_WHITE);
     97 	gs->bgcolor = gs->color(gs, C_BLACK);
     98 }
     99 
    100 void gfx_setcolor(gfx_surface_t* gs, uint32_t fg_argb8888, uint32_t bg_argb8888) {
    101 	gs->fgcolor = gs->color(gs, fg_argb8888);
    102 	gs->bgcolor = gs->color(gs, bg_argb8888);
    103 }
    104 
    105 void gfx_fill(gfx_surface_t* gs, uint32_t x0, uint32_t y0, uint32_t x1, uint32_t y1, uint32_t pxl) {
    106 	while (y0 < y1) {
    107 		gs->hline(gs, x0, y0, x1, pxl);
    108 		y0++;
    109 	}
    110 }
    111 
    112 void gfx_clear(gfx_surface_t* gs, uint32_t pxl) {
    113 	gfx_fill(gs, 0, 0, gs->width, gs->height, pxl);
    114 }
    115 
    116 void gfx_puts(gfx_surface_t *gs, uint32_t x, uint32_t y, const char* s) {
    117 	while (*s) {
    118 		gs->putc(gs, x, y, *s++);
    119 		x += CH_WIDTH;
    120 	}
    121 }
    122 
    123 void gfx_printf(gfx_surface_t* gs, uint32_t x, uint32_t y, const char* fmt, ...) {
    124 	char msg[128];
    125 	va_list ap;
    126 	va_start(ap, fmt);
    127 	vsnprintf(msg, sizeof(msg), fmt, ap);
    128 	va_end(ap);
    129 	gfx_puts(gs, x, y, msg);
    130 }
    131