From e688fdf4f0a3c96c05e06e8add2fa915698de478 Mon Sep 17 00:00:00 2001 From: koniifer Date: Sat, 7 Dec 2024 15:41:58 +0000 Subject: [PATCH] cool mandelbrot also fix circle rendering a bit --- Cargo.lock | 46 +++-- sysdata/libraries/render/src/software.hb | 107 +++++------ .../render_example/src/examples/mandelbrot.hb | 168 ++++++++++++++++++ sysdata/programs/render_example/src/main.hb | 2 +- sysdata/system_config.toml | 20 +-- 5 files changed, 248 insertions(+), 95 deletions(-) create mode 100644 sysdata/programs/render_example/src/examples/mandelbrot.hb diff --git a/Cargo.lock b/Cargo.lock index f6d8de51..38a01919 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -13,15 +13,15 @@ dependencies = [ [[package]] name = "allocator-api2" -version = "0.2.20" +version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45862d1c77f2228b9e10bc609d5bc203d86ebc9b87ad8d5d5167a6c9abf739d9" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" [[package]] name = "anyhow" -version = "1.0.93" +version = "1.0.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c95c10ba0b00a02636238b814946408b1322d5ac4760326e6fb8ec956d85775" +checksum = "c1fd03a028ef38ba2276dce7e33fcd6369c158a1bca17946c4b1b701891c1ff7" [[package]] name = "autocfg" @@ -73,9 +73,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "cc" -version = "1.2.2" +version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f34d93e62b03caf570cccc334cbc6c2fceca82f39211051345108adcba3eebdc" +checksum = "27f657647bcff5394bf56c7317665bbf790a137a50eaaa5c6bfbb9e27a518f2d" dependencies = [ "shlex", ] @@ -213,12 +213,12 @@ dependencies = [ [[package]] name = "hbbytecode" version = "0.1.0" -source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#c5d5301b7bbdc44a5e365381594604c710d9a980" +source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#71ba2c24865944bebb641fcd48afc9d87987404d" [[package]] name = "hblang" version = "0.1.0" -source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#c5d5301b7bbdc44a5e365381594604c710d9a980" +source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#71ba2c24865944bebb641fcd48afc9d87987404d" dependencies = [ "hashbrown", "hbbytecode", @@ -229,7 +229,7 @@ dependencies = [ [[package]] name = "hbvm" version = "0.1.0" -source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#c5d5301b7bbdc44a5e365381594604c710d9a980" +source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#71ba2c24865944bebb641fcd48afc9d87987404d" dependencies = [ "hbbytecode", ] @@ -433,9 +433,9 @@ checksum = "02034f8f6b3e7bf050f310fbaf6db0018b8e54b75598d0a4c97172054752fede" [[package]] name = "litemap" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "643cb0b8d4fcc284004d5fd0d67ccf61dfffadb7f75e1e71bc420f4688a3a704" +checksum = "4ee93343901ab17bd981295f2cf0026d4ad018c7c31ba84549a4ddbb47a45104" [[package]] name = "lock_api" @@ -464,9 +464,9 @@ dependencies = [ [[package]] name = "logos-codegen" -version = "0.14.2" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b32eb6b5f26efacd015b000bfc562186472cd9b34bdba3f6b264e2a052676d10" +checksum = "5f3303189202bb8a052bcd93d66b6c03e6fe70d9c7c47c0ea5e974955e54c876" dependencies = [ "beef", "fnv", @@ -474,14 +474,15 @@ dependencies = [ "proc-macro2", "quote", "regex-syntax", + "rustc_version", "syn", ] [[package]] name = "logos-derive" -version = "0.14.2" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e5d0c5463c911ef55624739fc353238b4e310f0144be1f875dc42fec6bfd5ec" +checksum = "774a1c225576486e4fdf40b74646f672c542ca3608160d348749693ae9d456e6" dependencies = [ "logos-codegen", ] @@ -827,20 +828,17 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "ureq" -version = "2.11.0" +version = "2.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b30e6f97efe1fa43535ee241ee76967d3ff6ff3953ebb430d8d55c5393029e7b" +checksum = "02d1a66277ed75f640d608235660df48c8e3c19f3b4edb6a263315626cc3c01d" dependencies = [ "base64", - "litemap", "log", "once_cell", "rustls", "rustls-pki-types", "url", "webpki-roots", - "yoke", - "zerofrom", ] [[package]] @@ -1047,9 +1045,9 @@ dependencies = [ [[package]] name = "yoke" -version = "0.7.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c5b1314b079b0930c31e3af543d8ee1757b1951ae1e1565ec704403a7240ca5" +checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40" dependencies = [ "serde", "stable_deref_trait", @@ -1071,9 +1069,9 @@ dependencies = [ [[package]] name = "zerofrom" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91ec111ce797d0e0784a1116d0ddcdbea84322cd79e5d5ad173daeba4f93ab55" +checksum = "cff3ee08c995dee1859d998dea82f7374f2826091dd9cd47def953cae446cd2e" dependencies = [ "zerofrom-derive", ] diff --git a/sysdata/libraries/render/src/software.hb b/sysdata/libraries/render/src/software.hb index 262461e6..612acf21 100644 --- a/sysdata/libraries/render/src/software.hb +++ b/sysdata/libraries/render/src/software.hb @@ -245,90 +245,77 @@ put_hline := fn(surface: Surface, y: uint, x0: uint, x1: uint, color: Color): vo x0 = x1 x1 = tmp } - // x0 = math.min(x0, x1) - memory.set(Color, &color, indexptr(surface, x0, y), @bitcast(x1 - x0 - 1)) - - return + memory.set(Color, &color, indexptr(surface, x0, y), @bitcast(x1 - x0)) } put_circle := fn(surface: Surface, pos: Vec2(uint), radius: uint, color: Color): void { x := 0 y := radius - error := @as(int, 3) - @intcast(2 * radius); - *indexptr(surface, pos.x + radius, pos.y) = color; - *indexptr(surface, pos.x - radius, pos.y) = color; - *indexptr(surface, pos.x, pos.y + radius) = color; - *indexptr(surface, pos.x, pos.y - radius) = color - - loop if y < x break else { - x += 1 - - if error > 0 { - y -= 1 - error += 4 * (@intcast(x) - @intcast(y)) + 10 - } else { + error := @as(int, 3) - 2 * @intcast(radius) + loop if x > y break else { + put_pixel(surface, pos + .(x, y), color) + put_pixel(surface, pos + .(-x, y), color) + put_pixel(surface, pos + .(x, -y), color) + put_pixel(surface, pos + .(-x, -y), color) + put_pixel(surface, pos + .(y, x), color) + put_pixel(surface, pos + .(-y, x), color) + put_pixel(surface, pos + .(y, -x), color) + put_pixel(surface, pos + .(-y, -x), color) + if error < 0 { error += 4 * @intcast(x) + 6 - }; - *indexptr(surface, pos.x + x, pos.y + y) = color; - *indexptr(surface, pos.x + y, pos.y + x) = color; - *indexptr(surface, pos.x - x, pos.y + y) = color; - *indexptr(surface, pos.x - y, pos.y + x) = color; - *indexptr(surface, pos.x + x, pos.y - y) = color; - *indexptr(surface, pos.x + y, pos.y - x) = color; - *indexptr(surface, pos.x - x, pos.y - y) = color; - *indexptr(surface, pos.x - y, pos.y - x) = color + } else { + error += 4 * (@intcast(x) - @intcast(y)) + 10 + y -= 1 + } + x += 1 } - - return } put_filled_circle := fn(surface: Surface, pos: Vec2(uint), radius: uint, color: Color): void { x := 0 y := radius - error := @as(int, 3) - @intcast(2 * radius) - put_hline(surface, pos.y - x, pos.x - radius, pos.x + radius, color); - *indexptr(surface, pos.x, pos.y + radius) = color; - *indexptr(surface, pos.x, pos.y - radius) = color + error := @as(int, 3) - 2 * @intcast(radius) - loop if y < x break else { - x += 1 + loop if x > y break else { + put_hline(surface, pos.y + y, pos.x - x, pos.x + x, color) + put_hline(surface, pos.y - y, pos.x - x, pos.x + x, color) - if error > 0 { - put_hline(surface, pos.y + y, pos.x - x, pos.x + x, color) - put_hline(surface, pos.y - y, pos.x - x, pos.x + x, color) - y -= 1 - error += 4 * (@intcast(x) - @intcast(y)) + 10 - } else { - error += 4 * @intcast(x) + 6 + if x != y { + put_hline(surface, pos.y + x, pos.x - y, pos.x + y, color) + put_hline(surface, pos.y - x, pos.x - y, pos.x + y, color) } - put_hline(surface, pos.y + x, pos.x - y, pos.x + y, color) - put_hline(surface, pos.y - x, pos.x - y, pos.x + y, color) - } - return + if error < 0 { + error += 4 * @intcast(x) + 6 + } else { + error += 4 * (@intcast(x) - @intcast(y)) + 10 + y -= 1 + } + x += 1 + } } 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) - @intcast(2 * radius) - memory.copy(Color, indexptr(source, source_pos.x - y, source_pos.y), indexptr(surface, pos.x - y, pos.y), 2 * y); - *indexptr(surface, pos.x, pos.y + y) = *indexptr(source, source_pos.x, source_pos.y + y); - *indexptr(surface, pos.x, pos.y - y) = *indexptr(source, source_pos.x, source_pos.y - y) + error := @as(int, 3) - 2 * @intcast(radius) - loop if y < x break else { - x += 1 + loop if x > y break else { + memory.copy(Color, indexptr(source, source_pos.x - x, source_pos.y + y), indexptr(surface, pos.x - x, pos.y + y), 2 * x) + memory.copy(Color, indexptr(source, source_pos.x - x, source_pos.y - y), indexptr(surface, pos.x - x, pos.y - y), 2 * x) - if error > 0 { - memory.copy(Color, indexptr(source, source_pos.x - x, source_pos.y + y), indexptr(surface, pos.x - x, pos.y + y), 2 * x) - memory.copy(Color, indexptr(source, source_pos.x - x, source_pos.y - y), indexptr(surface, pos.x - x, pos.y - y), 2 * x) - y -= 1 - error += 4 * (@intcast(x) - @intcast(y)) + 10 - } else { - error += 4 * @intcast(x) + 6 + if x != y { + memory.copy(Color, indexptr(source, source_pos.x - y, source_pos.y + x), indexptr(surface, pos.x - y, pos.y + x), 2 * y) + memory.copy(Color, indexptr(source, source_pos.x - y, source_pos.y - x), indexptr(surface, pos.x - y, pos.y - x), 2 * y) } - memory.copy(Color, indexptr(source, source_pos.x - y, source_pos.y + x), indexptr(surface, pos.x - y, pos.y + x), 2 * y) - memory.copy(Color, indexptr(source, source_pos.x - y, source_pos.y - x), indexptr(surface, pos.x - y, pos.y - x), 2 * y) + + if error < 0 { + error += 4 * @intcast(x) + 6 + } else { + error += 4 * (@intcast(x) - @intcast(y)) + 10 + y -= 1 + } + x += 1 } return diff --git a/sysdata/programs/render_example/src/examples/mandelbrot.hb b/sysdata/programs/render_example/src/examples/mandelbrot.hb new file mode 100644 index 00000000..21ba46c8 --- /dev/null +++ b/sysdata/programs/render_example/src/examples/mandelbrot.hb @@ -0,0 +1,168 @@ +// ln_f32 := fn(x: f32): f32 { +// if x <= 0 { +// return -1000000000000000.0 +// } +// approx := x - 1.0 +// i := 0 +// loop if i == 10 break else { +// exp_approx := exp_f32(approx) +// approx -= (exp_approx - x) / exp_approx +// i += 1 +// } +// return approx +// } + +// exp_f32 := fn(x: f32): f32 { +// sum := 1.0 +// term := 1.0 +// n := @as(int, 1) +// loop if n == 20 break else { +// term *= x / @floatcast(@itf(n)) +// sum += term +// if term < 0.000006 break +// n += 1 +// } +// return sum +// } + +// sqrt_f32 := fn(x: f32): f32 { +// if x <= 0 { +// return 0.0 +// } +// guess := x / 2.0 +// tolerance := 0.000001 +// loop { +// new_guess := (guess + x / guess) / 2.0 +// if guess - new_guess < tolerance { +// break +// } +// guess = new_guess +// } +// return guess +// } + +render := @use("lib:render") +sunset := @use("lib:sunset_proto"); +.{log} := @use("stn") + +// full mandelbrot +$X_MIN := -2.0 +$X_MAX := 0.47 +$Y_MIN := -1.12 +$Y_MAX := 1.12 + +// a minibrot +// $X_MIN := -0.94 +// $X_MAX := -0.93 +// $Y_MIN := 0.31 +// $Y_MAX := 0.306 + +// if you use the minibrot this should be at least 100 to actually see the minibrot, +// if you use the mandelbrot it looks best under 30 +$MAX_MAX_ITERATION := 30 + +$USE_SUNSET := true + +$COLOUR_R := 200 +$COLOUR_G := 100 +$COLOUR_B := 255 + +// $COLOUR_R := 255 +// $COLOUR_G := 255 +// $COLOUR_B := 255 + +// $INTERIOR_COLOUR := render.white +$INTERIOR_COLOUR := render.Color.{r: COLOUR_R, g: COLOUR_G, b: COLOUR_B, a: 255} + +example := fn(): void { + screen := @as(render.Surface, idk) + window := @as(?sunset.Window, null) + if USE_SUNSET { + sunset.client.find_server() + window = sunset.client.new(.(.(400, 240), .(400, 400), "Mandelbrot Set\0")) + if window == null { + log.error("got no window\0") + return + } + screen = window.surface + } else { + screen = render.init(false) + } + render.clear(screen, INTERIOR_COLOUR) + + max_iteration := 0 + prev_max_iteration := 0 + + x_scale := (X_MAX - X_MIN) / @floatcast(@itf(@bitcast(screen.width))) + y_scale := (Y_MAX - Y_MIN) / @floatcast(@itf(@bitcast(screen.height))) + + loop if max_iteration >= MAX_MAX_ITERATION break else { + py := 0 + loop if py == screen.height break else { + px := 0 + loop if px >= screen.width break else { + x0 := X_MIN + @floatcast(@itf(@bitcast(px))) * x_scale + y0 := Y_MIN + @floatcast(@itf(@bitcast(py))) * y_scale + + q := (x0 - 0.25) * (x0 - 0.25) + y0 * y0 + if q * (q + x0 - 0.25) <= 0.25 * y0 * y0 { + px += 1 + continue + } + + if (x0 + 1.0) * (x0 + 1.0) + y0 * y0 <= 0.0625 { + px += 1 + continue + } + + x := 0.0 + y := 0.0 + iteration := 0 + x2 := x * x + y2 := y * y + loop if iteration == max_iteration break else { + if x2 + y2 > 4.0 break + y = 2.0 * x * y + y0 + x = x2 - y2 + x0 + iteration += 1 + x2 = x * x + y2 = y * y + } + + smooth_value := @itf(@bitcast(iteration - prev_max_iteration / 10)) / @itf(@bitcast(max_iteration)) + smooth_value *= smooth_value * (3 - 2 * smooth_value) + if iteration < max_iteration & iteration > prev_max_iteration / 10 { + colour := render.Color.{ + r: @intcast(@fti(smooth_value * COLOUR_R)), + g: @intcast(@fti(smooth_value * COLOUR_G)), + b: @intcast(@fti(smooth_value * COLOUR_B)), + a: 0, + } + render.put_pixel(screen, .(px, py), colour) + } + // faster + if iteration >= max_iteration { + px += 2 + } else if iteration < 5 { + render.put_hline(screen, py, px, px + 5, .(0, 0, 0, 0)) + px += 5 + } else { + px += 1 + } + // slower but more slightly more accurate + // px += 1 + } + py += 1 + } + prev_max_iteration = max_iteration + max_iteration += 5 + if USE_SUNSET { + _ = sunset.client.send_frame(window) + } + } + // if USE_SUNSET { + // loop { + // _ = sunset.client.send_frame(window) + // } + // } +} \ 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 ab66cfa8..5273ce24 100644 --- a/sysdata/programs/render_example/src/main.hb +++ b/sysdata/programs/render_example/src/main.hb @@ -1 +1 @@ -.{example: main} := @use("./examples/orbit.hb") \ No newline at end of file +.{example: main} := @use("./examples/mandelbrot.hb") \ No newline at end of file diff --git a/sysdata/system_config.toml b/sysdata/system_config.toml index 84e2999b..8df697fb 100644 --- a/sysdata/system_config.toml +++ b/sysdata/system_config.toml @@ -22,11 +22,11 @@ resolution = "1024x768x24" [boot.limine.ableos.modules] -# [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.diskio_driver] -path = "boot:///diskio_driver.hbf" +[boot.limine.ableos.modules.sunset_server] +path = "boot:///sunset_server.hbf" [boot.limine.ableos.modules.ps2_mouse_driver] path = "boot:///ps2_mouse_driver.hbf" @@ -37,11 +37,11 @@ path = "boot:///ps2_mouse_driver.hbf" # [boot.limine.ableos.modules.ps2_driver] # path = "boot:///ps2_driver.hbf" -[boot.limine.ableos.modules.sunset_client] -path = "boot:///sunset_client.hbf" +# [boot.limine.ableos.modules.sunset_client] +# path = "boot:///sunset_client.hbf" -[boot.limine.ableos.modules.sunset_server] -path = "boot:///sunset_server.hbf" +# [boot.limine.ableos.modules.ablefetch] +# path = "boot:///ablefetch.hbf" -[boot.limine.ableos.modules.ablefetch] -path = "boot:///ablefetch.hbf" +# [boot.limine.ableos.modules.diskio_driver] +# path = "boot:///diskio_driver.hbf"