package main
Bitmap :: struct {
buffer: []u32,
width: u32,
height: u32,
}
draw_line :: proc(bitmap: ^Bitmap, x1, y1, x2, y2: i32, color: u32) {
xx1 := clamp(x1, 0, i32(bitmap.width - 1))
yy1 := clamp(y1, 0, i32(bitmap.height - 1))
xx2 := clamp(x2, 0, i32(bitmap.width - 1))
yy2 := clamp(y2, 0, i32(bitmap.height - 1))
sx: i32 = (xx1 < xx2 ? 1 : -1)
sy: i32 = (yy1 < yy2 ? 1 : -1)
dx: i32 = abs(xx2 - xx1)
dy: i32 = -abs(yy2 - yy1)
x := xx1
y := yy1
e := dx + dy
for {
bitmap.buffer[(u32(y) * bitmap.width) + u32(x)] = color
if x == xx2 && y == yy2 {
break
}
e2 := e * 2
if e2 >= dy {
e += dy
x += sx
}
if e2 <= dx {
e += dx
y += sy
}
}
}
draw_rect :: proc(bitmap: ^Bitmap, x1, y1, x2, y2: i32, color: u32) {
xx1 := clamp(x1, 0, i32(bitmap.width - 1))
yy1 := clamp(y1, 0, i32(bitmap.height - 1))
xx2 := clamp(x2, 0, i32(bitmap.width - 1))
yy2 := clamp(y2, 0, i32(bitmap.height - 1))
for y in yy1 ..= yy2 {
i := u32(y) * bitmap.width
bitmap.buffer[i + u32(xx1)] = color
bitmap.buffer[i + u32(xx2)] = color
}
iy1 := u32(yy1) * bitmap.width
iy2 := u32(yy2) * bitmap.width
for x in xx1 ..= xx2 {
bitmap.buffer[iy1 + u32(x)] = color
bitmap.buffer[iy2 + u32(x)] = color
}
}
draw_bitmap :: proc(dest, src: ^Bitmap, dx, dy: i32) {
draw_sub_bitmap(dest, src, dx, dy, 0, 0, src.width, src.height)
}
draw_sub_bitmap :: proc(dest, src: ^Bitmap, dx, dy: i32, sx1, sy1, sx2, sy2: u32) {
dxx := u32(dx)
dyy := u32(dy)
sw := sx2 - sx1
sh := sy2 - sy1
x1 := u32(0 if dx >= 0 else -dx)
x2 := sw if dxx + sw < dest.width else sw - (dxx + sw - dest.width)
y1 := u32(0 if dy >= 0 else -dy)
y2 := sh if dyy + sh < dest.height else sh - (dyy + sh - dest.height)
for y in y1 ..< y2 {
si := (y + sy1) * src.width
di := (y + dyy) * dest.width
for x in x1 ..< x2 {
dest.buffer[di + (x + dxx)] = src.buffer[si + (x + sx1)]
}
}
}