103 lines
2.6 KiB
C
103 lines
2.6 KiB
C
#include <stdint.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <graphics.h>
|
|
|
|
#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;
|
|
} |