From e6b972a7f3eade5d188ff23a160723e1030bd392 Mon Sep 17 00:00:00 2001 From: peony Date: Sat, 26 Oct 2024 16:02:47 +0200 Subject: [PATCH] Circle drawing, slightly bugged --- Cargo.lock | 6 +- sysdata/libraries/render/src/lib.hb | 5 +- sysdata/libraries/render/src/software.hb | 121 ++++++++++++++++-- sysdata/libraries/stn/src/math.hb | 4 +- .../render_example/src/examples/cube.hb | 2 +- .../render_example/src/examples/gravity.hb | 26 ++++ sysdata/programs/render_example/src/main.hb | 2 +- sysdata/system_config.toml | 12 +- 8 files changed, 152 insertions(+), 26 deletions(-) create mode 100644 sysdata/programs/render_example/src/examples/gravity.hb diff --git a/Cargo.lock b/Cargo.lock index 5b028ce..96eaa40 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -253,12 +253,12 @@ dependencies = [ [[package]] name = "hbbytecode" version = "0.1.0" -source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#faa8dd2e6fabe2e0e4a375e677171856da491c61" +source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#5b23a0661b10e9dcd492d5d97f8ad6077162a9d3" [[package]] name = "hblang" version = "0.1.0" -source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#faa8dd2e6fabe2e0e4a375e677171856da491c61" +source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#5b23a0661b10e9dcd492d5d97f8ad6077162a9d3" dependencies = [ "hashbrown 0.15.0", "hbbytecode", @@ -270,7 +270,7 @@ dependencies = [ [[package]] name = "hbvm" version = "0.1.0" -source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#faa8dd2e6fabe2e0e4a375e677171856da491c61" +source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#5b23a0661b10e9dcd492d5d97f8ad6077162a9d3" dependencies = [ "hbbytecode", ] diff --git a/sysdata/libraries/render/src/lib.hb b/sysdata/libraries/render/src/lib.hb index 66a68ee..aad9e1e 100644 --- a/sysdata/libraries/render/src/lib.hb +++ b/sysdata/libraries/render/src/lib.hb @@ -37,12 +37,15 @@ light_cyan := Color.(255, 255, 0, 255) put_pixel := mode.put_pixel put_rect := mode.put_rect put_filled_rect := mode.put_filled_rect +put_circle := mode.put_circle +put_filled_circle := mode.put_filled_circle +put_textured_circle := mode.put_textured_circle put_line := mode.put_line clear := mode.clear put_surface := mode.put_surface put_scaled := mode.put_scaled put_tri_wireframe := mode.put_tri_wireframe -put_tri_filled := mode.put_tri_filled +put_filled_tri := mode.put_filled_tri // thanks peony for these three! put_trirect := mode.put_trirect put_vline := mode.put_vline diff --git a/sysdata/libraries/render/src/software.hb b/sysdata/libraries/render/src/software.hb index 455d237..d205fbb 100644 --- a/sysdata/libraries/render/src/software.hb +++ b/sysdata/libraries/render/src/software.hb @@ -329,14 +329,14 @@ put_hline := fn(surface: Surface, y: uint, x0: uint, x1: uint, color: Color): vo return } -put_tri_wireframe := fn(surface: Surface, p0: Vec2(uint), p1: Vec2(uint), p2: Vec2(uint), color: Color): void { +put_tri := fn(surface: Surface, p0: Vec2(uint), p1: Vec2(uint), p2: Vec2(uint), color: Color): void { put_line(surface, p0, p1, color) put_line(surface, p1, p2, color) put_line(surface, p2, p0, color) return } -put_tri_filled := fn(surface: Surface, p0: Vec2(uint), p1: Vec2(uint), p2: Vec2(uint), color: Color): void { +put_filled_tri := fn(surface: Surface, p0: Vec2(uint), p1: Vec2(uint), p2: Vec2(uint), color: Color): void { if p2.y < p0.y { tmp := p0 p0 = p2 @@ -357,24 +357,121 @@ put_tri_filled := fn(surface: Surface, p0: Vec2(uint), p1: Vec2(uint), p2: Vec2( primary_dx := @as(int, @bitcast(p2.x - p0.x)) primary_dy := @as(int, @bitcast(p2.y - p0.y)) + primary_x := p0.x + primary_step := primary_dx / primary_dy primary_error := @as(int, 2) * primary_dx - primary_dy - secondary_dx := @as(int, @bitcast(p1.x - p0.x)) secondary_dy := @as(int, @bitcast(p1.y - p0.y)) + secondary_x := p0.x + secondary_step := secondary_dx / secondary_dy secondary_error := @as(int, 2) * secondary_dx - secondary_dy - - y := p0.y - loop if y > p2.y break else { - if primary_error > 0 { - x += xi - primary_error += 2 * (dx - dy) - } else { - primary_error += 2 * dx - } + y := p0.y + loop if y > p1.y break else { + put_pixel(surface, .(primary_x, y), color) + put_pixel(surface, .(secondary_x, y), color) + primary_x = @as(uint, @bitcast(@as(int, @bitcast(primary_x)) + primary_step)) + secondary_x = @as(uint, @bitcast(@as(int, @bitcast(secondary_x)) + secondary_step)) + y += 1 + } + + secondary_dx = @as(int, @bitcast(p2.x - p1.x)) + secondary_dy = @as(int, @bitcast(p2.y - p1.y)) + secondary_x = p1.x + secondary_step = secondary_dx / secondary_dy + secondary_error = @as(int, 2) * secondary_dx - secondary_dy + + loop if y > p2.y break else { + put_pixel(surface, .(primary_x, y), color) + put_pixel(surface, .(secondary_x, y), color) + primary_x = @as(uint, @bitcast(@as(int, @bitcast(primary_x)) + primary_step)) + secondary_x = @as(uint, @bitcast(@as(int, @bitcast(secondary_x)) + secondary_step)) y += 1 } + 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 } \ No newline at end of file diff --git a/sysdata/libraries/stn/src/math.hb b/sysdata/libraries/stn/src/math.hb index 563e9c3..7835cae 100644 --- a/sysdata/libraries/stn/src/math.hb +++ b/sysdata/libraries/stn/src/math.hb @@ -41,11 +41,11 @@ sin_i := fn(theta_deg: int, amplitude: int): int { quadrant := theta / 90 theta = theta % 90 - sign := 1 - ((quadrant & 2) >> 1) * 2 + sign := @as(int, 1) - ((quadrant & 2) >> 1) * 2 complement := quadrant & 1 index := theta * (1 - complement) + (90 - theta) * complement - sin_value := SIN_TABLE[index] * sign + sin_value := SIN_TABLE[@intcast(index)] * sign return (sin_value * amplitude + 5000) / 10000 } diff --git a/sysdata/programs/render_example/src/examples/cube.hb b/sysdata/programs/render_example/src/examples/cube.hb index 0318b98..20e5e6d 100644 --- a/sysdata/programs/render_example/src/examples/cube.hb +++ b/sysdata/programs/render_example/src/examples/cube.hb @@ -5,7 +5,7 @@ example := fn(): void { screen := render.init(true) loop { render.clear(screen, render.black) - render.put_tri_filled(screen, .(128, 256), .(512, 512), .(10, 10), .(255, 255, 255, 255)) + render.put_filled_tri(screen, .(128, 256), .(512, 512), .(10, 10), .(255, 255, 255, 255)) render.sync(screen) } return diff --git a/sysdata/programs/render_example/src/examples/gravity.hb b/sysdata/programs/render_example/src/examples/gravity.hb new file mode 100644 index 0000000..c213762 --- /dev/null +++ b/sysdata/programs/render_example/src/examples/gravity.hb @@ -0,0 +1,26 @@ +.{Vec2, sin_i, cos_i} := @use("../../../../libraries/stn/src/lib.hb").math +render := @use("../../../../libraries/render/src/lib.hb") + +able_bmp := @embed("./assets/able.bmp") +mini_bmp := @embed("./assets/mini.bmp") + +example := fn(): void { + able := render.image.surface_from_bmp(@bitcast(&able_bmp)) + mini := render.image.surface_from_bmp(@bitcast(&mini_bmp)) + + angle := @as(int, 0) + + screen := render.init(true) + + loop { + render.clear(screen, render.black) + render.put_filled_circle(screen, .(screen.width / 2, screen.height / 2), 128, render.light_yellow) + render.put_circle(screen, .(screen.width / 2, screen.height / 2), 256, render.light_blue) + render.put_textured_circle(screen, able, .(able.width / 2, able.height / 2), .(screen.width / 2 + @intcast(sin_i(angle, @as(int, 256))), screen.height / 2 + @intcast(cos_i(angle, @as(int, 256)))), able.width / 2 - 1) + render.put_textured_circle(screen, mini, .(mini.width / 2, mini.height / 2), .(screen.width / 2 + @intcast(sin_i(angle + 180, @as(int, 256))), screen.height / 2 + @intcast(cos_i(angle + 180, @as(int, 256)))), mini.width / 2 - 1) + render.sync(screen) + + angle += 1 + } + return +} \ No newline at end of file diff --git a/sysdata/programs/render_example/src/main.hb b/sysdata/programs/render_example/src/main.hb index 8f2d2c0..2495e15 100644 --- a/sysdata/programs/render_example/src/main.hb +++ b/sysdata/programs/render_example/src/main.hb @@ -1,3 +1,3 @@ -.{example} := @use("./examples/cube.hb") +.{example} := @use("./examples/gravity.hb") main := example \ No newline at end of file diff --git a/sysdata/system_config.toml b/sysdata/system_config.toml index 6515647..6e3318b 100644 --- a/sysdata/system_config.toml +++ b/sysdata/system_config.toml @@ -26,17 +26,17 @@ resolution = "1600x900x24" # [boot.limine.ableos.modules.diskio_driver] # path = "boot:///diskio_driver.hbf" -# [boot.limine.ableos.modules.render_example] -# path = "boot:///render_example.hbf" +[boot.limine.ableos.modules.render_example] +path = "boot:///render_example.hbf" # [boot.limine.ableos.modules.serial_driver_test] # path = "boot:///serial_driver_test.hbf" -[boot.limine.ableos.modules.horizon] -path = "boot:///horizon.hbf" +# [boot.limine.ableos.modules.horizon] +# path = "boot:///horizon.hbf" -[boot.limine.ableos.modules.horizon_testing_program] -path = "boot:///horizon_testing_program.hbf" +# [boot.limine.ableos.modules.horizon_testing_program] +# path = "boot:///horizon_testing_program.hbf" # [boot.limine.ableos.modules.dt_buffer_test] # path = "boot:///dt_buffer_test.hbf"