draw :: (screen: *Screen, x: s64, y: s64, char: PIXEL_TYPE = .PIXEL_SOLID, color: COLOR = .FG_WHITE) { using screen; if x >= 0 && x < width && y >= 0 && y < height { buffer[y * width + x].type = char; buffer[y * width + x].color = color; } } draw_line :: (screen: *Screen, x1: s64, y1: s64, x2: s64, y2: s64, char: PIXEL_TYPE = .PIXEL_SOLID, color: COLOR = .FG_WHITE) { x, y, dx, dy, dx1, dy1, xe, ye, px, py : s64; dx = x2 - x1; dy = y2 - y1; dx1 = abs(dx); dy1 = abs(dy); px = 2 * dy1 - dx1; py = 2 * dx1 - dy1; if dy1 <= dx1 { if dx >= 0 { x = x1; y = y1; xe = x2; } else { x = x2; y = y2; xe = x1; } draw(screen, x, y, char, color); for 0..xe { x += 1; if px < 0 { px += 2 * dy1; } else { if (dx < 0 && dy < 0) || (dx > 0 && dy > 0) then y += 1; else y -= 1; px += 2 * (dy1 - dx1); draw(screen, x, y, char, color); } } } else { if dy >= 0 { x = x1; y = y1; ye = y2; } else { x = x2; y = y2; ye = y1; } draw(screen, x, y, char, color); for 0..ye { y += 1; if py <= 0 { py += 2 * dx1; } else { if (dx < 0 && dy < 0 ) || (dx > 0 && dy > 0) then x += 1; else x -= 1; py += 2 * (dx1 - dy1); } draw(screen, x, y, char, color); } } } draw_triangle :: (screen: *Screen, x1: s64, y1: s64, x2: s64, y2: s64, x3: s64, y3: s64, char: PIXEL_TYPE = .PIXEL_SOLID, color: COLOR = .FG_WHITE) { draw_line(x1, y1, x2, y2, char, color); draw_line(x2, y2, x3, y3, char, color); draw_line(x3, y3, x1, y1, char, color); } clip :: (screen: *Screen, x: *s64, y: *s64) { using screen; if x < 0 then x = 0; if x >= width then x = width; if y < 0 then y = 0; if y >= height then y = height; } fill :: (screen: *Screen, x1: s64, y1: s64, x2: s64, y2: s64, char: PIXEL_TYPE = .PIXEL_SOLID, color: COLOR = .FG_WHITE) { clip(screen, *x1, *y1); clip(screen, *x2, *y2); for x: x1..x2 { for y: y1..y2 { draw(x, y, char, color); } } } draw_string :: (screen: *Screen, x: s64, y: s64, text: string, c: COLOR = .FG_WHITE) { assert(false, "not implemented"); }