#include #include #include #include #define incptr(p, n) ((void *)(((uintptr_t)(p)) + (n))) #include "u_vga16.termfont.inc" void putpixel(gfx_context *ctx, uint64_t x, uint64_t y, uint32_t clr) { if(x >= ctx->width || y >= ctx->height) return; uint64_t loc = \ y * ctx->pitch + \ x * ctx->bpp; uint32_t *fb = incptr(ctx->buffer, loc); *fb = clr; } void draw_line(gfx_context *ctx, uint64_t x0, uint64_t x1, uint64_t y0, uint64_t y1, uint32_t clr) { int64_t dx = x1 > x0 ? x1 - x0 : x0 - x1; int64_t dy = y1 > y0 ? y1 - y0 : y0 - y1; int sx = x1 > x0 ? 1 : -1; int sy = y1 > y0 ? 1 : -1; uint64_t x = x0, y = y0; int64_t diff = dx - dy; while(1) { putpixel(ctx, x, y, clr); if(x == x1 && y == y1) break; if((2*diff) > -dy) { diff -= dy; x += sx; } else { diff += dx; y += sy; } } } void draw_rect(gfx_context *ctx, uint64_t x, uint64_t y, uint64_t width, uint64_t height, uint32_t clr) { for(uint64_t _x = x; _x <= x+width; _x++) { putpixel(ctx, _x, y, clr); putpixel(ctx, _x, y+height, clr); } for(uint64_t _y = y; _y <= y+height; _y++) { putpixel(ctx, x, _y, clr); putpixel(ctx, x+width, _y, clr); } } void putCharacter(gfx_context *ctx, uint64_t x, uint64_t y, uint32_t clr_fg, uint32_t clr_bg, char c) { unsigned char *chr = c ? font[(int)c-0x20]: font[0]; if(x >= ctx->width || y >= ctx->height) return; uint64_t loc = \ y * ctx->pitch + \ x * ctx->bpp; uint32_t *fb = incptr(ctx->buffer, loc); for(int row = 0; row < 16; row++) { for(int col = 0; col < 8; col++) { fb[col] = ((chr[row]>>(7-col))&0x1) ? clr_fg : clr_bg; } fb = incptr(fb, ctx->pitch); } } void flip(gfx_context *ctx) { for(uint64_t y = 0; y < ctx->height; y++) { memcpy( incptr(ctx->addr, y*ctx->pitch), incptr(ctx->buffer, y*ctx->pitch), ctx->width*ctx->bpp); } } gfx_context *framebuffer_make_subcontext(gfx_context *ctx, uint64_t x, uint64_t y, uint64_t width, uint64_t height) { gfx_context *out = malloc(sizeof(gfx_context)); uint64_t loc = \ y * ctx->pitch + \ x * ctx->bpp; out->width = width; out->height = height; out->bpp = ctx->bpp; out->pitch = ctx->pitch; out->addr = incptr(ctx->addr, loc); out->size = ctx->pitch * (height); out->buffer = calloc(1, out->size); return out; }