add c and jai
This commit is contained in:
107
jai/modules/Console_Render/draw.jai
Normal file
107
jai/modules/Console_Render/draw.jai
Normal file
@@ -0,0 +1,107 @@
|
||||
// "Squashes" two dimensional coordinates onto the one dimensional screen buffer
|
||||
draw :: (using screen: *Screen, p: Vec2s64, char: u8 = DEFAULT_PIXEL_CHAR) {
|
||||
if p.x >= 0 && p.x < width && p.y >= 0 && p.y < height {
|
||||
buffer[p.y * width + p.x] = char;
|
||||
}
|
||||
}
|
||||
|
||||
// Implementation of the Bresenham line algorithm
|
||||
// https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm
|
||||
draw_line :: (screen: *Screen, p1: Vec2s64, p2: Vec2s64, char: u8 = DEFAULT_PIXEL_CHAR) {
|
||||
p1_c := p1;
|
||||
p2_c := p2;
|
||||
|
||||
dx := abs(p2_c.x - p1_c.x);
|
||||
dy := -abs(p2_c.y - p1_c.y);
|
||||
sx := ifx p1_c.x < p2_c.x then 1 else -1;
|
||||
sy := ifx p1_c.y < p2_c.y then 1 else -1;
|
||||
|
||||
err := dx + dy;
|
||||
e2 : s64;
|
||||
|
||||
while true {
|
||||
draw(screen, Vec2s64.{p1_c.x, p1_c.y}, char);
|
||||
|
||||
if p1_c.x == p2_c.x && p1_c.y == p2_c.y then break;
|
||||
|
||||
e2 = 2 * err;
|
||||
|
||||
if e2 >= dy {
|
||||
err += dy;
|
||||
p1_c.x += sx;
|
||||
}
|
||||
|
||||
if e2 <= dx {
|
||||
err += dx;
|
||||
p1_c.y += sy;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
draw_triangle :: (screen: *Screen, p1: Vec2s64, p2: Vec2s64, p3: Vec2s64, char: u8 = DEFAULT_PIXEL_CHAR) {
|
||||
draw_line(screen, p1, p2, char);
|
||||
draw_line(screen, p2, p3, char);
|
||||
draw_line(screen, p3, p1, char);
|
||||
}
|
||||
|
||||
draw_triangle :: (screen: *Screen, t: Triangle, char: u8 = DEFAULT_PIXEL_CHAR) {
|
||||
draw_triangle(screen, t.p1, t.p2, t.p3, char);
|
||||
}
|
||||
|
||||
draw_quad :: (screen: *Screen, p1: Vec2s64, p2: Vec2s64, char: u8 = DEFAULT_PIXEL_CHAR) {
|
||||
// (x1, y1) => top left
|
||||
// (x2, y2) => bottom right
|
||||
|
||||
draw_line(screen, .{p1.x, p1.y}, .{p1.x, p2.y}, char);
|
||||
draw_line(screen, .{p1.x, p2.y}, .{p2.x, p2.y}, char);
|
||||
draw_line(screen, .{p2.x, p2.y}, .{p2.x, p1.y}, char);
|
||||
draw_line(screen, .{p2.x, p1.y}, .{p1.x, p1.y}, char);
|
||||
}
|
||||
|
||||
draw_quad :: (screen: *Screen, p1: Vec2s64, p2: Vec2s64, p3: Vec2s64, p4: Vec2s64, char: u8 = DEFAULT_PIXEL_CHAR) {
|
||||
// (x1, y1) => top left
|
||||
// (x2, y2) => bottom left
|
||||
// (x3, y3) => bottom right
|
||||
// (x4, y4) => top right
|
||||
|
||||
draw_line(screen, .{p1.x, p1.y}, .{p2.x, p2.y}, char);
|
||||
draw_line(screen, .{p2.x, p2.y}, .{p3.x, p3.y}, char);
|
||||
draw_line(screen, .{p3.x, p3.y}, .{p4.x, p4.y}, char);
|
||||
draw_line(screen, .{p4.x, p4.y}, .{p1.x, p1.y}, char);
|
||||
}
|
||||
|
||||
draw_quad :: (screen: *Screen, q: Quad, char: u8 = DEFAULT_PIXEL_CHAR) {
|
||||
draw_quad(screen, q.p1, q.p2, q.p3, q.p4, char);
|
||||
}
|
||||
|
||||
draw_text :: (using screen: *Screen, p: Vec2s64, s: string) {
|
||||
if p.x >= 0 && p.x < width && p.y >= 0 && p.y < height {
|
||||
for cast([]u8)s {
|
||||
buffer[(p.y * width + p.x) + it_index] = it;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// When attempting to draw outside of the visible screen, "clip" the pixels
|
||||
// by setting their position to the maximum width / height available
|
||||
clip :: (using screen: *Screen, p: *Vec2s64) {
|
||||
if p.x < 0 then p.x = 0;
|
||||
if p.x >= width then p.x = width;
|
||||
if p.y < 0 then p.y = 0;
|
||||
if p.y >= height then p.y = height;
|
||||
}
|
||||
|
||||
fill :: (screen: *Screen, p1: Vec2s64, p2: Vec2s64, char: u8 = DEFAULT_PIXEL_CHAR) {
|
||||
clip(screen, *p1);
|
||||
clip(screen, *p2);
|
||||
|
||||
for x: p1.x..p2.x {
|
||||
for y: p1.y..p2.y {
|
||||
draw(screen, .{x, y}, char);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fill_entire_screen :: (screen: *Screen, char: u8 = DEFAULT_PIXEL_CHAR) {
|
||||
fill(screen, .{0,0}, .{screen.width, screen.height}, char);
|
||||
}
|
||||
Reference in New Issue
Block a user