diff --git a/sysdata/libraries/render/src/lib.hb b/sysdata/libraries/render/src/lib.hb index 4e656a2ad..00279a3f1 100644 --- a/sysdata/libraries/render/src/lib.hb +++ b/sysdata/libraries/render/src/lib.hb @@ -39,6 +39,9 @@ put_pixel := mode.put_pixel put_rect := mode.put_rect put_filled_rect := mode.put_filled_rect put_trirect := mode.put_trirect +put_circle := mode.put_circle +put_filled_circle := mode.put_filled_circle +put_textured_circle := mode.put_textured_circle put_line := mode.put_line put_vline := mode.put_vline put_hline := mode.put_hline diff --git a/sysdata/libraries/render/src/software.hb b/sysdata/libraries/render/src/software.hb index efc8d92eb..0c4780e66 100644 --- a/sysdata/libraries/render/src/software.hb +++ b/sysdata/libraries/render/src/software.hb @@ -251,6 +251,90 @@ put_hline := fn(surface: Surface, y: uint, x0: uint, x1: uint, color: Color): vo return } + +put_circle := fn(surface: Surface, pos: Vec2(uint), radius: uint, color: Color): void { + x := 0 + y := radius + error := @as(int, 3) - @as(int, @intcast(2 * radius)); + *@inline(indexptr, surface, pos.x + radius, pos.y) = color; + *@inline(indexptr, surface, pos.x - radius, pos.y) = color; + *@inline(indexptr, surface, pos.x, pos.y + radius) = color; + *@inline(indexptr, surface, pos.x, pos.y - radius) = color + + loop if y < x break else { + x += 1 + + if error > 0 { + y -= 1 + error += 4 * (@as(int, @intcast(x)) - @as(int, @intcast(y))) + 10 + } else { + error += 4 * @intcast(x) + 6 + }; + *@inline(indexptr, surface, pos.x + x, pos.y + y) = color; + *@inline(indexptr, surface, pos.x + y, pos.y + x) = color; + *@inline(indexptr, surface, pos.x - x, pos.y + y) = color; + *@inline(indexptr, surface, pos.x - y, pos.y + x) = color; + *@inline(indexptr, surface, pos.x + x, pos.y - y) = color; + *@inline(indexptr, surface, pos.x + y, pos.y - x) = color; + *@inline(indexptr, surface, pos.x - x, pos.y - y) = color; + *@inline(indexptr, surface, pos.x - y, pos.y - x) = color + } + + return +} + +put_filled_circle := fn(surface: Surface, pos: Vec2(uint), radius: uint, color: Color): void { + x := 0 + y := radius + error := @as(int, 3) - @as(int, @intcast(2 * radius)) + @inline(put_hline, surface, pos.y - x, pos.x - radius, pos.x + radius, color); + *@inline(indexptr, surface, pos.x, pos.y + radius) = color; + *@inline(indexptr, surface, pos.x, pos.y - radius) = color + + loop if y < x break else { + x += 1 + + if error > 0 { + @inline(put_hline, surface, pos.y + y, pos.x - x, pos.x + x, color) + @inline(put_hline, surface, pos.y - y, pos.x - x, pos.x + x, color) + y -= 1 + error += 4 * (@as(int, @intcast(x)) - @as(int, @intcast(y))) + 10 + } else { + error += 4 * @intcast(x) + 6 + } + @inline(put_hline, surface, pos.y + x, pos.x - y, pos.x + y, color) + @inline(put_hline, surface, pos.y - x, pos.x - y, pos.x + y, color) + } + + return +} + +put_textured_circle := fn(surface: Surface, source: Surface, source_pos: Vec2(uint), pos: Vec2(uint), radius: uint): void { + x := 0 + y := radius + error := @as(int, 3) - @as(int, @intcast(2 * radius)) + @inline(memory.copy, Color, @inline(indexptr, source, source_pos.x - y, source_pos.y), @inline(indexptr, surface, pos.x - y, pos.y), 2 * y); + *@inline(indexptr, surface, pos.x, pos.y + y) = *@inline(indexptr, source, source_pos.x, source_pos.y + y); + *@inline(indexptr, surface, pos.x, pos.y - y) = *@inline(indexptr, source, source_pos.x, source_pos.y - y) + + loop if y < x break else { + x += 1 + + if error > 0 { + @inline(memory.copy, Color, @inline(indexptr, source, source_pos.x - x, source_pos.y + y), @inline(indexptr, surface, pos.x - x, pos.y + y), 2 * x) + @inline(memory.copy, Color, @inline(indexptr, source, source_pos.x - x, source_pos.y - y), @inline(indexptr, surface, pos.x - x, pos.y - y), 2 * x) + y -= 1 + error += 4 * (@as(int, @intcast(x)) - @as(int, @intcast(y))) + 10 + } else { + error += 4 * @intcast(x) + 6 + } + @inline(memory.copy, Color, @inline(indexptr, source, source_pos.x - y, source_pos.y + x), @inline(indexptr, surface, pos.x - y, pos.y + x), 2 * y) + @inline(memory.copy, Color, @inline(indexptr, source, source_pos.x - y, source_pos.y - x), @inline(indexptr, surface, pos.x - y, pos.y - x), 2 * y) + } + + return +} + utf8_len_table := [u8].(0, 0, 2, 3) put_text := fn(surface: Surface, font: Font, pos: Vec2(uint), color: Color, str: ^u8): void {