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)] } } }