forked from AbleOS/ableos
113 lines
2.7 KiB
Plaintext
113 lines
2.7 KiB
Plaintext
.{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
|
|
} |