.{draw_pixel, screenidx, Transform, Point, Rect, Buffer, FB_WIDTH} := @use("rel:lib.hb") ColorBGRA := @use("rel:color.hb").ColorBGRA math := @use("../../../libraries/stn/src/lib.hb").math /* draws a filled rectangle to the screen will be optimised later */ rect_fill := fn(buffer: Buffer, pos: Point, tr: Transform, color: ColorBGRA): void { n := 0 loop if n == tr.height * tr.width break else { *(buffer.write + screenidx(.(n % tr.width + pos.x, n / tr.width + pos.y))) = color n += 1 } return } /* draws a wireframe rectangle to the screen will also be optimised later */ rect_line := fn(buffer: Buffer, pos: Point, tr: Transform, color: ColorBGRA, thickness: int): void { t := 0 y := 0 x := 0 loop if t == thickness break else { y = pos.y x = pos.x loop if y == pos.y + tr.height break else { *(buffer.write + pos.x + t + FB_WIDTH * y) = color; *(buffer.write + pos.x + tr.width - t + FB_WIDTH * y) = color y += 1 } loop if x == pos.x + tr.width break else { *(buffer.write + x + (pos.y + t) * FB_WIDTH) = color; *(buffer.write + x + (pos.y + tr.height - t) * FB_WIDTH) = color x += 1 } t += 1 } return } // do not use, use line() instead line_low := fn(buffer: Buffer, p0: Point, p1: Point, color: ColorBGRA): void { dx := p1.x - p0.x dy := p1.y - p0.y yi := 1 if dy < 0 { yi = 0 - 1 dy = 0 - dy } D := 2 * dy - dx y := p0.y x := p0.x loop if x == p1.x break else { *(buffer.write + x + y * FB_WIDTH) = color if D > 0 { y += yi D += 2 * (dy - dx) } else { D += 2 * dy } x += 1 } return } // do not use, use line() instead line_high := fn(buffer: Buffer, p0: Point, p1: Point, color: ColorBGRA): void { dx := p1.x - p0.x dy := p1.y - p0.y xi := 1 if dy < 0 { xi = 0 - 1 dx = 0 - dx } D := 2 * dx - dy x := p0.x y := p0.y loop if y == p1.y break else { *(buffer.write + x + y * FB_WIDTH) = color if D > 0 { x += xi D += 2 * (dx - dy) } else { D += 2 * dx } y += 1 } return } /* implementation of Bresenham's line algorithm TODO: thickness, might need better math library */ line := fn(buffer: Buffer, p0: Point, p1: Point, color: ColorBGRA, thickness: int): void { if math.abs(p1.y - p0.y) < math.abs(p1.x - p0.x) { if p0.x > p1.x { line_low(buffer, p1, p0, color) } else { line_low(buffer, p0, p1, color) } } else { if p0.y > p1.y { line_high(buffer, p1, p0, color) } else { line_high(buffer, p0, p1, color) } } return } // theoretically draws a wireframe polygon to the screen. untested. tri_line := fn(buffer: Buffer, p0: Point, p1: Point, p2: Point, color: ColorBGRA, thickness: int): void { line(buffer, p0, p1, color, thickness) line(buffer, p1, p2, color, thickness) line(buffer, p2, p0, color, thickness) return }