From ee68a2662c1e0f0138bd2ed84f489d8903355e21 Mon Sep 17 00:00:00 2001
From: koniifer <koniifer@proton.me>
Date: Sat, 14 Dec 2024 16:39:45 +0000
Subject: [PATCH 1/6] broken struct method things

---
 Cargo.lock                                    |  47 +-
 .../holeybytes/kernel_services/mem_serve.rs   |   6 +-
 .../horizon_api/src/widgets/label.hb          |  10 +-
 sysdata/libraries/render/README.md            |   5 +-
 sysdata/libraries/render/src/image/bmp.hb     |   4 +-
 sysdata/libraries/render/src/image/qoi.hb     |   2 +-
 sysdata/libraries/render/src/lib.hb           |  61 +-
 sysdata/libraries/render/src/software.hb      | 736 +++++++++---------
 sysdata/libraries/sunset_proto/src/client.hb  |   4 +-
 sysdata/libraries/sunset_proto/src/server.hb  |  20 +-
 sysdata/programs/ablefetch/src/main.hb        |   8 +-
 .../render_example/src/examples/amogus.hb     |  16 +-
 .../render_example/src/examples/colors.hb     |   9 +-
 .../render_example/src/examples/image.hb      |  16 +-
 .../render_example/src/examples/lines.hb      |  12 +-
 .../render_example/src/examples/mandelbrot.hb |  33 +-
 .../render_example/src/examples/orbit.hb      |  20 +-
 .../render_example/src/examples/random.hb     |   4 +-
 .../render_example/src/examples/square.hb     |  11 +-
 .../render_example/src/examples/surface.hb    |  21 +-
 .../src/examples/tactical_screen.hb           |  28 +-
 .../render_example/src/examples/text.hb       |  26 +-
 sysdata/programs/render_example/src/main.hb   |   2 +-
 sysdata/programs/sunset_server/src/main.hb    |  18 +-
 sysdata/system_config.toml                    |   8 +-
 25 files changed, 532 insertions(+), 595 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index 38a0191..469feb6 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -73,9 +73,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
 
 [[package]]
 name = "cc"
-version = "1.2.3"
+version = "1.2.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "27f657647bcff5394bf56c7317665bbf790a137a50eaaa5c6bfbb9e27a518f2d"
+checksum = "9157bbaa6b165880c27a4293a474c91cdcf265cc68cc829bf10be0964a391caf"
 dependencies = [
  "shlex",
 ]
@@ -213,12 +213,12 @@ dependencies = [
 [[package]]
 name = "hbbytecode"
 version = "0.1.0"
-source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#71ba2c24865944bebb641fcd48afc9d87987404d"
+source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#91e35b72eeab9c230d52ec8636faf1dc0f96554a"
 
 [[package]]
 name = "hblang"
 version = "0.1.0"
-source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#71ba2c24865944bebb641fcd48afc9d87987404d"
+source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#91e35b72eeab9c230d52ec8636faf1dc0f96554a"
 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#71ba2c24865944bebb641fcd48afc9d87987404d"
+source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#91e35b72eeab9c230d52ec8636faf1dc0f96554a"
 dependencies = [
  "hbbytecode",
 ]
@@ -421,9 +421,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
 
 [[package]]
 name = "libc"
-version = "0.2.167"
+version = "0.2.168"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "09d6582e104315a817dff97f75133544b2e094ee22447d2acf4a74e189ba06fc"
+checksum = "5aaeb2981e0606ca11d79718f8bb01164f1d6ed75080182d3abf017e6d244b6d"
 
 [[package]]
 name = "limine"
@@ -455,18 +455,18 @@ checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
 
 [[package]]
 name = "logos"
-version = "0.14.2"
+version = "0.14.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1c6b6e02facda28ca5fb8dbe4b152496ba3b1bd5a4b40bb2b1b2d8ad74e0f39b"
+checksum = "7251356ef8cb7aec833ddf598c6cb24d17b689d20b993f9d11a3d764e34e6458"
 dependencies = [
  "logos-derive",
 ]
 
 [[package]]
 name = "logos-codegen"
-version = "0.14.3"
+version = "0.14.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5f3303189202bb8a052bcd93d66b6c03e6fe70d9c7c47c0ea5e974955e54c876"
+checksum = "59f80069600c0d66734f5ff52cc42f2dabd6b29d205f333d61fd7832e9e9963f"
 dependencies = [
  "beef",
  "fnv",
@@ -474,15 +474,14 @@ dependencies = [
  "proc-macro2",
  "quote",
  "regex-syntax",
- "rustc_version",
  "syn",
 ]
 
 [[package]]
 name = "logos-derive"
-version = "0.14.3"
+version = "0.14.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "774a1c225576486e4fdf40b74646f672c542ca3608160d348749693ae9d456e6"
+checksum = "24fb722b06a9dc12adb0963ed585f19fc61dc5413e6a9be9422ef92c091e731d"
 dependencies = [
  "logos-codegen",
 ]
@@ -594,9 +593,9 @@ dependencies = [
 
 [[package]]
 name = "rustls"
-version = "0.23.19"
+version = "0.23.20"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "934b404430bb06b3fae2cba809eb45a1ab1aecd64491213d7c3301b88393f8d1"
+checksum = "5065c3f250cbd332cd894be57c40fa52387247659b14a2d6041d121547903b1b"
 dependencies = [
  "log",
  "once_cell",
@@ -609,9 +608,9 @@ dependencies = [
 
 [[package]]
 name = "rustls-pki-types"
-version = "1.10.0"
+version = "1.10.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "16f1201b3c9a7ee8039bcadc17b7e605e2945b27eee7631788c1bd2b0643674b"
+checksum = "d2bf47e6ff922db3825eb750c4e2ff784c6ff8fb9e13046ef6a1d1c5401b0b37"
 
 [[package]]
 name = "rustls-webpki"
@@ -644,24 +643,24 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
 
 [[package]]
 name = "semver"
-version = "1.0.23"
+version = "1.0.24"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b"
+checksum = "3cb6eb87a131f756572d7fb904f6e7b68633f09cca868c5df1c4b8d1a694bbba"
 
 [[package]]
 name = "serde"
-version = "1.0.215"
+version = "1.0.216"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f"
+checksum = "0b9781016e935a97e8beecf0c933758c97a5520d32930e460142b4cd80c6338e"
 dependencies = [
  "serde_derive",
 ]
 
 [[package]]
 name = "serde_derive"
-version = "1.0.215"
+version = "1.0.216"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0"
+checksum = "46f859dbbf73865c6627ed570e78961cd3ac92407a2d117204c49232485da55e"
 dependencies = [
  "proc-macro2",
  "quote",
diff --git a/kernel/src/holeybytes/kernel_services/mem_serve.rs b/kernel/src/holeybytes/kernel_services/mem_serve.rs
index 3f9c6b2..a2cb42a 100644
--- a/kernel/src/holeybytes/kernel_services/mem_serve.rs
+++ b/kernel/src/holeybytes/kernel_services/mem_serve.rs
@@ -99,7 +99,8 @@ pub fn memory_msg_handler(
             let count = u32::from_le_bytes(msg_vec[1..5].try_into().unwrap_unchecked()) as usize;
             let src = u64::from_le_bytes(msg_vec[5..13].try_into().unwrap_unchecked()) as *const u8;
             let dest = u64::from_le_bytes(msg_vec[13..21].try_into().unwrap_unchecked()) as *mut u8;
-
+            debug_assert!(src.addr() & 0xFFFF000000000000 != 0);
+            debug_assert!(dest.addr() & 0xFFFF000000000000 != 0);
             src.copy_to_nonoverlapping(dest, count);
         },
         5 => unsafe {
@@ -107,7 +108,8 @@ pub fn memory_msg_handler(
             let size = u32::from_le_bytes(msg_vec[5..9].try_into().unwrap_unchecked()) as usize;
             let src = u64::from_le_bytes(msg_vec[9..17].try_into().unwrap_unchecked()) as *const u8;
             let dest = u64::from_le_bytes(msg_vec[17..25].try_into().unwrap_unchecked()) as *mut u8;
-
+            debug_assert!(src.addr() & 0xFFFF000000000000 != 0);
+            debug_assert!(dest.addr() & 0xFFFF000000000000 != 0);
             memset(dest, src, count, size);
         },
         _ => {
diff --git a/sysdata/libraries/horizon_api/src/widgets/label.hb b/sysdata/libraries/horizon_api/src/widgets/label.hb
index 3241b52..aa8b97e 100644
--- a/sysdata/libraries/horizon_api/src/widgets/label.hb
+++ b/sysdata/libraries/horizon_api/src/widgets/label.hb
@@ -16,9 +16,9 @@ Label := struct {
 	fg: Color,
 
 	new_label := fn(text: ^u8, width: uint): Self {
-		text_surface := render.new_surface(width, 20)
+		text_surface := render.Surface.new(width, 20)
 		text_length := string.length(text)
-		label := Self.(3, true, text_surface, text, text_length, render.black, render.white)
+		label := Self.(3, true, text_surface, text, text_length, render.BLACK, render.WHITE)
 		return label
 	}
 
@@ -39,8 +39,8 @@ Label := struct {
 
 render_label_to_surface := fn(surface: Surface, label: Label, font: Font, pos: Vec2(uint)): void {
 	if label.is_dirty {
-		render.clear(label.surface, label.bg)
-		render.put_text(label.surface, font, .(0, 0), label.fg, label.text)
+		label.surface.clear(label.bg)
+		label.surface.put_text(font, .(0, 0), label.fg, label.text)
 	}
-	render.put_surface(surface, label.surface, pos, false)
+	surface.put_surface(label.surface, pos, false)
 }
\ No newline at end of file
diff --git a/sysdata/libraries/render/README.md b/sysdata/libraries/render/README.md
index ac765eb..d112825 100644
--- a/sysdata/libraries/render/README.md
+++ b/sysdata/libraries/render/README.md
@@ -3,7 +3,4 @@ Rendering interface for SVGA and Software renderers
 # TODO:
 
 - SVGA Driver
-  - needs pci driver
-  - needs init (requiring program)
-- Double Buffer mode for Software renderer
-  - needs init (requiring program)
\ No newline at end of file
+  - needs pci driver
\ No newline at end of file
diff --git a/sysdata/libraries/render/src/image/bmp.hb b/sysdata/libraries/render/src/image/bmp.hb
index 9c48dac..3efdd95 100644
--- a/sysdata/libraries/render/src/image/bmp.hb
+++ b/sysdata/libraries/render/src/image/bmp.hb
@@ -42,8 +42,8 @@ from := fn(bmp: ^u8): ?Surface {
 	}
 
 	lhs := Surface.(@bitcast(bmp + file_header.offset), info_header.width, info_header.height, info_header.width * info_header.height)
-	rhs := new_surface(info_header.width, info_header.height)
-	put_surface(rhs, lhs, .(0, 0), true)
+	rhs := Surface.new(info_header.width, info_header.height)
+	rhs.put_surface(lhs, .(0, 0), true)
 
 	return rhs
 }
\ No newline at end of file
diff --git a/sysdata/libraries/render/src/image/qoi.hb b/sysdata/libraries/render/src/image/qoi.hb
index a090e3a..2593aa4 100644
--- a/sysdata/libraries/render/src/image/qoi.hb
+++ b/sysdata/libraries/render/src/image/qoi.hb
@@ -44,7 +44,7 @@ from := fn(qoi: ^u8): ?Surface {
 		return null
 	}
 
-	surface := new_surface(width, height)
+	surface := Surface.new(width, height)
 	index := @as([Color; 64], idk)
 
 	run := 0
diff --git a/sysdata/libraries/render/src/lib.hb b/sysdata/libraries/render/src/lib.hb
index 00279a3..3a334ef 100644
--- a/sysdata/libraries/render/src/lib.hb
+++ b/sysdata/libraries/render/src/lib.hb
@@ -6,52 +6,23 @@ text := @use("text.hb")
 mode := software
 
 init := mode.init
-doublebuffer := mode.doublebuffer
 Surface := mode.Surface
-new_surface := mode.new_surface
-surface_from_ptr := mode.surface_from_ptr
-clone_surface := mode.clone_surface
-free_surface := mode.free_surface
-index := mode.index
-indexptr := mode.indexptr
 
 // Colours
 Color := packed struct {b: u8, g: u8, r: u8, a: u8}
-$white := Color.(255, 255, 255, 255)
-$black := Color.(0, 0, 0, 255)
-$gray := Color.(127, 127, 127, 255)
-$red := Color.(0, 0, 205, 255)
-$green := Color.(0, 205, 0, 255)
-$yellow := Color.(0, 205, 205, 255)
-$blue := Color.(205, 0, 0, 255)
-$magenta := Color.(205, 0, 205, 255)
-$cyan := Color.(205, 205, 0, 255)
-$light_gray := Color.(229, 229, 229, 255)
-$light_red := Color.(0, 0, 255, 255)
-$light_green := Color.(0, 255, 0, 255)
-$light_yellow := Color.(0, 255, 255, 255)
-$light_blue := Color.(255, 0, 0, 255)
-$light_magenta := Color.(255, 0, 255, 255)
-$light_cyan := Color.(255, 255, 0, 255)
-
-// Drawing
-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
-clear := mode.clear
-put_surface := mode.put_surface
-put_text := mode.put_text
-// thanks peony for these three!
-//put_trirect := mode.put_trirect
-//put_vline := mode.put_vline
-//put_hline := mode.put_hline
-
-// Display
-sync := mode.sync
\ No newline at end of file
+$WHITE := Color.(255, 255, 255, 255)
+$BLACK := Color.(0, 0, 0, 255)
+$GRAY := Color.(127, 127, 127, 255)
+$RED := Color.(0, 0, 205, 255)
+$GREEN := Color.(0, 205, 0, 255)
+$YELLOW := Color.(0, 205, 205, 255)
+$BLUE := Color.(205, 0, 0, 255)
+$MAGENTA := Color.(205, 0, 205, 255)
+$CYAN := Color.(205, 205, 0, 255)
+$LIGHT_GRAY := Color.(229, 229, 229, 255)
+$LIGHT_RED := Color.(0, 0, 255, 255)
+$LIGHT_GREEN := Color.(0, 255, 0, 255)
+$LIGHT_YELLOW := Color.(0, 255, 255, 255)
+$LIGHT_BLUE := Color.(255, 0, 0, 255)
+$LIGHT_MAGENTA := Color.(255, 0, 255, 255)
+$LIGHT_CYAN := Color.(255, 255, 0, 255)
\ No newline at end of file
diff --git a/sysdata/libraries/render/src/software.hb b/sysdata/libraries/render/src/software.hb
index 612acf2..d4959f2 100644
--- a/sysdata/libraries/render/src/software.hb
+++ b/sysdata/libraries/render/src/software.hb
@@ -1,459 +1,441 @@
-.{math, memory, dt} := @use("../../stn/src/lib.hb");
-.{Color, text} := @use("lib.hb");
+.{math, memory, dt} := @use("stn");
+.{Color, text} := @use("lib:render");
 .{get_glyph, get_glyph_unicode, Font, UNC_TABLE_SIZE} := text;
 .{Vec2} := math
 
 // safety: don't use before init() or you will get a memory access violation
 framebuffer := memory.dangling(Color)
-
-Surface := struct {
-	buf: ^Color,
-	width: uint,
-	height: uint,
-	size: uint,
-}
-
-new_surface := fn(width: uint, height: uint): Surface {
-	return .(
-		memory.alloc(Color, width * height),
-		width,
-		height,
-		width * height,
-	)
-}
-
-clone_surface := fn(surface: ^Surface): Surface {
-	new := new_surface(surface.width, surface.height)
-	memory.copy(Color, surface.buf, new.buf, @intcast(surface.size))
-	return new
-}
+utf8_len_table := [u8].(0, 0, 2, 3)
 
 init := fn(doublebuffer: bool): Surface {
 	framebuffer = dt.get(^Color, "framebuffer/fb0/ptr\0")
 	width := dt.get(uint, "framebuffer/fb0/width\0")
 	height := dt.get(uint, "framebuffer/fb0/height\0")
 	if doublebuffer {
-		return new_surface(width, height)
+		return Surface.new(width, height)
 	} else {
 		return .(framebuffer, width, height, width * height)
 	}
 }
 
-$clear := fn(surface: Surface, color: Color): void {
-	memory.set(Color, &color, surface.buf, surface.width * surface.height)
-}
+Surface := struct {
+	buf: ^Color,
+	width: uint,
+	height: uint,
+	size: uint,
 
-$sync := fn(surface: Surface): void {
-	memory.copy(Color, surface.buf, framebuffer, @bitcast(surface.width * surface.height))
-}
-
-$index := fn(surface: Surface, x: uint, y: uint): uint {
-	return x + surface.width * y
-}
-
-$indexptr := fn(surface: Surface, x: uint, y: uint): ^Color {
-	return surface.buf + index(surface, x, y)
-}
-
-$put_pixel := fn(surface: Surface, pos: Vec2(uint), color: Color): void {
-	return *indexptr(surface, pos.x, pos.y) = color
-}
-
-put_filled_rect := fn(surface: Surface, pos: Vec2(uint), tr: Vec2(uint), color: Color): void {
-	top_start_idx := indexptr(surface, pos.x, pos.y)
-	bottom_start_idx := indexptr(surface, pos.x, pos.y + tr.y - 1)
-	rows_to_fill := tr.y
-
-	loop if rows_to_fill <= 1 break else {
-		memory.set(Color, &color, top_start_idx, tr.x)
-		memory.set(Color, &color, bottom_start_idx, tr.x)
-
-		top_start_idx += surface.width
-		bottom_start_idx -= surface.width
-		rows_to_fill -= 2
+	new := fn(width: uint, height: uint): Self {
+		size := width * height
+		return .(
+			memory.alloc(Color, size),
+			width,
+			height,
+			size,
+		)
 	}
 
-	if rows_to_fill == 1 {
-		memory.set(Color, &color, top_start_idx, tr.x)
+	clone := fn(self: ^Self): Self {
+		new_self := Self.new(self.width, self.height)
+		memory.copy(Color, self.buf, new_self.buf, self.size)
+		return new_self
+	}
+	$clear := fn(self: Self, color: Color): void {
+		memory.set(Color, &color, self.buf, self.size)
 	}
 
-	return
-}
-
-put_rect := fn(surface: Surface, pos: Vec2(uint), tr: Vec2(uint), color: Color): void {
-	start_idx := indexptr(surface, pos.x, pos.y)
-	end_idx := indexptr(surface, pos.x, pos.y + tr.y)
-	right_start_idx := indexptr(surface, pos.x + tr.x, pos.y)
-
-	loop if start_idx > end_idx break else {
-		*start_idx = color;
-		*right_start_idx = color
-		start_idx += surface.width
-		right_start_idx += surface.width
+	$sync := fn(self: Self): void {
+		memory.copy(Color, self.buf, framebuffer, self.size)
 	}
 
-	memory.set(Color, &color, indexptr(surface, pos.x, pos.y), @bitcast(tr.x + 1))
-	memory.set(Color, &color, indexptr(surface, pos.x, pos.y + tr.y), @bitcast(tr.x + 1))
-
-	return
-}
-
-put_line_low := fn(surface: Surface, p0: Vec2(uint), p1: Vec2(uint), color: Color): void {
-	dx := @as(int, @bitcast(p1.x - p0.x))
-	dy := @as(int, @bitcast(p1.y - p0.y))
-	yi := 1
-	if dy < 0 {
-		yi = -1
-		dy = -dy
+	$index := fn(self: Self, x: uint, y: uint): uint {
+		return x + self.width * y
 	}
-	D := @as(int, 2) * dy - dx
-	y := p0.y
-	x := p0.x
-	loop if x == p1.x break else {
-		*indexptr(surface, x, y) = color
-		if D > 0 {
-			y += yi
-			D += 2 * (dy - dx)
+
+	$indexptr := fn(self: Self, x: uint, y: uint): ^Color {
+		return self.buf + self.index(x, y)
+	}
+
+	$put_pixel := fn(self: Self, pos: Vec2(uint), color: Color): void {
+		*self.indexptr(pos.x, pos.y) = color
+	}
+
+	put_filled_rect := fn(self: Self, pos: Vec2(uint), tr: Vec2(uint), color: Color): void {
+		top_start_idx := self.indexptr(pos.x, pos.y)
+		bottom_start_idx := self.indexptr(pos.x, pos.y + tr.y - 1)
+		rows_to_fill := tr.y
+
+		loop if rows_to_fill <= 1 break else {
+			memory.set(Color, &color, top_start_idx, tr.x)
+			memory.set(Color, &color, bottom_start_idx, tr.x)
+
+			top_start_idx += self.width
+			bottom_start_idx -= self.width
+			rows_to_fill -= 2
+		}
+
+		if rows_to_fill == 1 {
+			memory.set(Color, &color, top_start_idx, tr.x)
+		}
+	}
+
+	put_rect := fn(self: Self, pos: Vec2(uint), tr: Vec2(uint), color: Color): void {
+		start_idx := self.indexptr(pos.x, pos.y)
+		end_idx := self.indexptr(pos.x, pos.y + tr.y)
+		right_start_idx := self.indexptr(pos.x + tr.x, pos.y)
+
+		loop if start_idx > end_idx break else {
+			*start_idx = color;
+			*right_start_idx = color
+			start_idx += self.width
+			right_start_idx += self.width
+		}
+
+		memory.set(Color, &color, self.indexptr(pos.x, pos.y), @bitcast(tr.x + 1))
+		memory.set(Color, &color, self.indexptr(pos.x, pos.y + tr.y), @bitcast(tr.x + 1))
+	}
+
+	put_line_low := fn(self: Self, p0: Vec2(uint), p1: Vec2(uint), color: Color): void {
+		dx := @as(int, @bitcast(p1.x - p0.x))
+		dy := @as(int, @bitcast(p1.y - p0.y))
+		yi := 1
+		if dy < 0 {
+			yi = -1
+			dy = -dy
+		}
+		D := @as(int, 2) * dy - dx
+		y := p0.y
+		x := p0.x
+		loop if x == p1.x break else {
+			*self.indexptr(x, y) = color
+			if D > 0 {
+				y += yi
+				D += 2 * (dy - dx)
+			} else {
+				D += 2 * dy
+			}
+			x += 1
+		}
+	}
+
+	put_line_high := fn(self: Self, p0: Vec2(uint), p1: Vec2(uint), color: Color): void {
+		dx := @as(int, @bitcast(p1.x - p0.x))
+		dy := @as(int, @bitcast(p1.y - p0.y))
+		xi := 1
+		if dy < 0 {
+			xi = -1
+			dx = -dx
+		}
+		D := @as(int, 2) * dx - dy
+		x := p0.x
+		y := p0.y
+		loop if y == p1.y break else {
+			*self.indexptr(x, y) = color
+			if D > 0 {
+				x += xi
+				D += 2 * (dx - dy)
+			} else {
+				D += 2 * dx
+			}
+			y += 1
+		}
+	}
+
+	put_line := fn(self: Self, p0: Vec2(uint), p1: Vec2(uint), color: Color): void {
+		if math.abs(uint, p1.y - p0.y) < math.abs(uint, p1.x - p0.x) {
+			if p0.x > p1.x {
+				@inline(put_line_low, self, p1, p0, color)
+			} else {
+				@inline(put_line_low, self, p0, p1, color)
+			}
 		} else {
-			D += 2 * dy
-		}
-		x += 1
-	}
-	return
-}
-
-put_line_high := fn(surface: Surface, p0: Vec2(uint), p1: Vec2(uint), color: Color): void {
-	dx := @as(int, @bitcast(p1.x - p0.x))
-	dy := @as(int, @bitcast(p1.y - p0.y))
-	xi := 1
-	if dy < 0 {
-		xi = -1
-		dx = -dx
-	}
-	D := @as(int, 2) * dx - dy
-	x := p0.x
-	y := p0.y
-	loop if y == p1.y break else {
-		*indexptr(surface, x, y) = color
-		if D > 0 {
-			x += xi
-			D += 2 * (dx - dy)
-		} else {
-			D += 2 * dx
-		}
-		y += 1
-	}
-	return
-}
-
-put_line := fn(surface: Surface, p0: Vec2(uint), p1: Vec2(uint), color: Color): void {
-	if math.abs(uint, p1.y - p0.y) < math.abs(uint, p1.x - p0.x) {
-		if p0.x > p1.x {
-			@inline(put_line_low, surface, p1, p0, color)
-		} else {
-			@inline(put_line_low, surface, p0, p1, color)
-		}
-	} else {
-		if p0.y > p1.y {
-			@inline(put_line_high, surface, p1, p0, color)
-		} else {
-			@inline(put_line_high, surface, p0, p1, color)
+			if p0.y > p1.y {
+				@inline(put_line_high, self, p1, p0, color)
+			} else {
+				@inline(put_line_high, self, p0, p1, color)
+			}
 		}
 	}
-	return
-}
 
-put_surface := fn(surface: Surface, top: Surface, pos: Vec2(uint), flip_v: bool): void {
-	src_top_cursor := top.buf
-	src_bottom_cursor := top.buf + top.width * (top.height - 1)
+	put_surface := fn(self: Self, top: Self, pos: Vec2(uint), flip_v: bool): void {
+		src_top_cursor := top.buf
+		src_bottom_cursor := top.buf + top.width * (top.height - 1)
 
-	dst_top_idx := indexptr(surface, pos.x, pos.y)
-	dst_bottom_idx := indexptr(surface, pos.x, pos.y + top.height - 1)
+		dst_top_idx := self.indexptr(pos.x, pos.y)
+		dst_bottom_idx := self.indexptr(pos.x, pos.y + top.height - 1)
 
-	dst_increment := surface.width
+		dst_increment := self.width
 
-	if flip_v {
-		dst_increment = -dst_increment
-		tmp := dst_top_idx
-		dst_top_idx = dst_bottom_idx
-		dst_bottom_idx = tmp
-	}
-
-	rows_to_copy := top.height
-
-	loop if rows_to_copy <= 1 break else {
-		memory.copy(Color, src_top_cursor, dst_top_idx, top.width)
-		memory.copy(Color, src_bottom_cursor, dst_bottom_idx, top.width)
-
-		dst_top_idx += dst_increment
-		dst_bottom_idx -= dst_increment
-		src_top_cursor += top.width
-		src_bottom_cursor -= top.width
-		rows_to_copy -= 2
-	}
-
-	if rows_to_copy == 1 {
-		memory.copy(Color, src_top_cursor, dst_top_idx, top.width)
-	}
-
-	return
-}
-
-// peony-made
-put_trirect := fn(surface: Surface, pos: Vec2(uint), size: Vec2(int), color0: Color, color1: Color): void {
-	step := Vec2(int).(1, 1)
-	if size.x < 0 {
-		step.x = -1
-	}
-	if size.y < 0 {
-		step.y /= @bitcast(size.x)
-	}
-
-	start_y := pos.y
-	target := pos + @bitcast(size)
-
-	loop if pos.x == target.x break else {
-		@inline(put_vline, surface, pos.x, pos.y, target.y, color0)
-		@inline(put_vline, surface, pos.x, pos.y, start_y, color1)
-		pos += @bitcast(step)
-	}
-
-	return
-}
-
-// peony-made
-put_vline := fn(surface: Surface, x: uint, y0: uint, y1: uint, color: Color): void {
-	if y1 < y0 {
-		tmp := y0
-		y0 = y1
-		y1 = tmp
-	}
-	y := y0
-
-	loop if y == y1 break else {
-		*indexptr(surface, x, y) = color
-		y += 1
-	}
-
-	return
-}
-
-// peony-made
-put_hline := fn(surface: Surface, y: uint, x0: uint, x1: uint, color: Color): void {
-	if x1 < x0 {
-		tmp := x0
-		x0 = x1
-		x1 = tmp
-	}
-	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) - 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
-		} else {
-			error += 4 * (@intcast(x) - @intcast(y)) + 10
-			y -= 1
-		}
-		x += 1
-	}
-}
-
-put_filled_circle := fn(surface: Surface, pos: Vec2(uint), radius: uint, color: Color): void {
-	x := 0
-	y := radius
-	error := @as(int, 3) - 2 * @intcast(radius)
-
-	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 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)
+		if flip_v {
+			dst_increment = -dst_increment
+			tmp := dst_top_idx
+			dst_top_idx = dst_bottom_idx
+			dst_bottom_idx = tmp
 		}
 
-		if error < 0 {
-			error += 4 * @intcast(x) + 6
-		} else {
-			error += 4 * (@intcast(x) - @intcast(y)) + 10
-			y -= 1
-		}
-		x += 1
-	}
-}
+		rows_to_copy := top.height
 
-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) - 2 * @intcast(radius)
+		loop if rows_to_copy <= 1 break else {
+			memory.copy(Color, src_top_cursor, dst_top_idx, top.width)
+			memory.copy(Color, src_bottom_cursor, dst_bottom_idx, top.width)
 
-	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 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)
+			dst_top_idx += dst_increment
+			dst_bottom_idx -= dst_increment
+			src_top_cursor += top.width
+			src_bottom_cursor -= top.width
+			rows_to_copy -= 2
 		}
 
-		if error < 0 {
-			error += 4 * @intcast(x) + 6
-		} else {
-			error += 4 * (@intcast(x) - @intcast(y)) + 10
-			y -= 1
+		if rows_to_copy == 1 {
+			memory.copy(Color, src_top_cursor, dst_top_idx, top.width)
 		}
-		x += 1
 	}
 
-	return
-}
+	// peony-made
+	put_trirect := fn(self: Self, pos: Vec2(uint), size: Vec2(int), color0: Color, color1: Color): void {
+		step := Vec2(int).(1, 1)
+		if size.x < 0 {
+			step.x = -1
+		}
+		if size.y < 0 {
+			step.y /= @bitcast(size.x)
+		}
 
-utf8_len_table := [u8].(0, 0, 2, 3)
+		start_y := pos.y
+		target := pos + @bitcast(size)
 
-put_text := fn(surface: Surface, font: Font, pos: Vec2(uint), color: Color, str: ^u8): void {
-	cursor := Vec2(uint).(pos.x, pos.y)
+		loop if pos.x == target.x break else {
+			@inline(put_vline, self, pos.x, pos.y, target.y, color0)
+			@inline(put_vline, self, pos.x, pos.y, start_y, color1)
+			pos += @bitcast(step)
+		}
+	}
 
-	max_y := surface.height - font.height
-	next_line_y := font.height + font.line_gap
-	char_advance := font.width + font.char_gap
-	surface_width := surface.width
+	// peony-made
+	put_vline := fn(self: Self, x: uint, y0: uint, y1: uint, color: Color): void {
+		if y1 < y0 {
+			tmp := y0
+			y0 = y1
+			y1 = tmp
+		}
+		y := y0
 
-	loop if *str == 0 break else {
-		if cursor.y > max_y break
+		loop if y == y1 break else {
+			*self.indexptr(x, y) = color
+			y += 1
+		}
+	}
 
-		glyph_data := @as(^u8, idk)
-		code_point := @as(uint, 0)
+	// peony-made
+	put_hline := fn(self: Self, y: uint, x0: uint, x1: uint, color: Color): void {
+		if x1 < x0 {
+			tmp := x0
+			x0 = x1
+			x1 = tmp
+		}
+		memory.set(Color, &color, self.indexptr(x0, y), @bitcast(x1 - x0))
+	}
 
-		if (*str & 0x80) == 0 {
-			if *str == 10 {
-				cursor.x = pos.x
-				cursor.y += next_line_y
-				str += 1
-				continue
+	put_circle := fn(self: Self, pos: Vec2(uint), radius: uint, color: Color): void {
+		x := 0
+		y := radius
+		error := @as(int, 3) - 2 * @intcast(radius)
+		loop if x > y break else {
+			self.put_pixel(pos + .(x, y), color)
+			self.put_pixel(pos + .(-x, y), color)
+			self.put_pixel(pos + .(x, -y), color)
+			self.put_pixel(pos + .(-x, -y), color)
+			self.put_pixel(pos + .(y, x), color)
+			self.put_pixel(pos + .(-y, x), color)
+			self.put_pixel(pos + .(y, -x), color)
+			self.put_pixel(pos + .(-y, -x), color)
+			if error < 0 {
+				error += 4 * @intcast(x) + 6
+			} else {
+				error += 4 * (@intcast(x) - @intcast(y)) + 10
+				y -= 1
+			}
+			x += 1
+		}
+	}
+
+	put_filled_circle := fn(self: Self, pos: Vec2(uint), radius: uint, color: Color): void {
+		x := 0
+		y := radius
+		error := @as(int, 3) - 2 * @intcast(radius)
+
+		loop if x > y break else {
+			self.put_hline(pos.y + y, pos.x - x, pos.x + x, color)
+			self.put_hline(pos.y - y, pos.x - x, pos.x + x, color)
+
+			if x != y {
+				self.put_hline(pos.y + x, pos.x - y, pos.x + y, color)
+				self.put_hline(pos.y - x, pos.x - y, pos.x + y, color)
 			}
 
-			if font.unicode == null {
-				if *str > font.num_glyphs {
+			if error < 0 {
+				error += 4 * @intcast(x) + 6
+			} else {
+				error += 4 * (@intcast(x) - @intcast(y)) + 10
+				y -= 1
+			}
+			x += 1
+		}
+	}
+
+	put_textured_circle := fn(self: Self, source: Self, source_pos: Vec2(uint), pos: Vec2(uint), radius: uint): void {
+		x := 0
+		y := radius
+		error := @as(int, 3) - 2 * @intcast(radius)
+
+		loop if x > y break else {
+			memory.copy(Color, source.indexptr(source_pos.x - x, source_pos.y + y), self.indexptr(pos.x - x, pos.y + y), 2 * x)
+			memory.copy(Color, source.indexptr(source_pos.x - x, source_pos.y - y), self.indexptr(pos.x - x, pos.y - y), 2 * x)
+
+			if x != y {
+				memory.copy(Color, source.indexptr(source_pos.x - y, source_pos.y + x), self.indexptr(pos.x - y, pos.y + x), 2 * y)
+				memory.copy(Color, source.indexptr(source_pos.x - y, source_pos.y - x), self.indexptr(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
+		}
+	}
+
+	put_text := fn(self: Self, font: Font, pos: Vec2(uint), color: Color, str: ^u8): void {
+		cursor := Vec2(uint).(pos.x, pos.y)
+
+		max_y := self.height - font.height
+		next_line_y := font.height + font.line_gap
+		char_advance := font.width + font.char_gap
+		self_width := self.width
+
+		loop if *str == 0 break else {
+			if cursor.y > max_y break
+
+			glyph_data := @as(^u8, idk)
+			code_point := @as(uint, 0)
+
+			if (*str & 0x80) == 0 {
+				if *str == 10 {
+					cursor.x = pos.x
+					cursor.y += next_line_y
 					str += 1
 					continue
 				}
-				glyph_data = get_glyph(font, *str)
-			} else {
-				if *str < UNC_TABLE_SIZE {
-					glyph_index := *(font.unicode + *str)
-					if glyph_index == 0xFFFF {
+
+				if font.unicode == null {
+					if *str > font.num_glyphs {
 						str += 1
 						continue
 					}
-					glyph_data = font.data + glyph_index * font.bytes_per_glyph
+					glyph_data = get_glyph(font, *str)
 				} else {
+					if *str < UNC_TABLE_SIZE {
+						glyph_index := *(font.unicode + *str)
+						if glyph_index == 0xFFFF {
+							str += 1
+							continue
+						}
+						glyph_data = font.data + glyph_index * font.bytes_per_glyph
+					} else {
+						str += 1
+						continue
+					}
+				}
+				str += 1
+			} else if font.unicode != null {
+				first_byte := *str
+				num_bytes := @as(uint, 0)
+
+				num_bytes = utf8_len_table[first_byte >> 5 & 0x3]
+
+				if num_bytes == 0 {
 					str += 1
 					continue
 				}
-			}
-			str += 1
-		} else if font.unicode != null {
-			first_byte := *str
-			num_bytes := @as(uint, 0)
 
-			num_bytes = utf8_len_table[first_byte >> 5 & 0x3]
+				code_point = first_byte & (0x7F >> num_bytes | 0x1F)
 
-			if num_bytes == 0 {
-				str += 1
-				continue
-			}
+				valid_sequence := true
+				bytes_processed := 1
 
-			code_point = first_byte & (0x7F >> num_bytes | 0x1F)
-
-			valid_sequence := true
-			bytes_processed := 1
-
-			loop if bytes_processed >= num_bytes break else {
-				str += 1
-				if *str == 0 | (*str & 0xC0) != 0x80 {
-					valid_sequence = false
+				loop if bytes_processed >= num_bytes break else {
+					str += 1
+					if *str == 0 | (*str & 0xC0) != 0x80 {
+						valid_sequence = false
+					}
+					if valid_sequence == false {
+						break
+					}
+					code_point = code_point << 6 | *str & 0x3F
+					bytes_processed += 1
 				}
+
 				if valid_sequence == false {
-					break
+					str += 1
+					continue
 				}
-				code_point = code_point << 6 | *str & 0x3F
-				bytes_processed += 1
-			}
 
-			if valid_sequence == false {
 				str += 1
-				continue
+
+				if code_point == 10 {
+					cursor.x = pos.x
+					cursor.y += next_line_y
+					continue
+				}
+
+				if code_point >= UNC_TABLE_SIZE {
+					continue
+				}
+
+				glyph_index := *(font.unicode + code_point)
+				if glyph_index == 0xFFFF {
+					continue
+				}
+				glyph_data = font.data + glyph_index * font.bytes_per_glyph
 			}
 
-			str += 1
-
-			if code_point == 10 {
+			if cursor.x + font.width >= self_width {
 				cursor.x = pos.x
 				cursor.y += next_line_y
-				continue
 			}
 
-			if code_point >= UNC_TABLE_SIZE {
-				continue
-			}
+			dest := self.indexptr(cursor.x, cursor.y)
+			rows := font.height
 
-			glyph_index := *(font.unicode + code_point)
-			if glyph_index == 0xFFFF {
-				continue
-			}
-			glyph_data = font.data + glyph_index * font.bytes_per_glyph
-		}
+			loop if rows == 0 break else {
+				byte := *glyph_data
+				pixel_dest := dest
+				mask := @as(u8, 0x80)
+				bits := font.width
 
-		if cursor.x + font.width >= surface_width {
-			cursor.x = pos.x
-			cursor.y += next_line_y
-		}
-
-		dest := indexptr(surface, cursor.x, cursor.y)
-		rows := font.height
-
-		loop if rows == 0 break else {
-			byte := *glyph_data
-			pixel_dest := dest
-			mask := @as(u8, 0x80)
-			bits := font.width
-
-			loop if bits == 0 break else {
-				if (byte & mask) != 0 {
-					*pixel_dest = color
+				loop if bits == 0 break else {
+					if (byte & mask) != 0 {
+						*pixel_dest = color
+					}
+					pixel_dest += 1
+					mask >>= 1
+					if mask == 0 & bits > 0 {
+						glyph_data += 1
+						byte = *glyph_data
+						mask = 0x80
+					}
+					bits -= 1
 				}
-				pixel_dest += 1
-				mask >>= 1
-				if mask == 0 & bits > 0 {
+
+				if mask != 0x80 {
 					glyph_data += 1
-					byte = *glyph_data
-					mask = 0x80
 				}
-				bits -= 1
+				dest += self_width
+				rows -= 1
 			}
 
-			if mask != 0x80 {
-				glyph_data += 1
-			}
-			dest += surface_width
-			rows -= 1
+			cursor.x += char_advance
 		}
-
-		cursor.x += char_advance
 	}
-
-	return
 }
\ No newline at end of file
diff --git a/sysdata/libraries/sunset_proto/src/client.hb b/sysdata/libraries/sunset_proto/src/client.hb
index 01d5762..981949b 100644
--- a/sysdata/libraries/sunset_proto/src/client.hb
+++ b/sysdata/libraries/sunset_proto/src/client.hb
@@ -1,6 +1,6 @@
 .{math: .{Vec2}, buffer, log, memory, string} := @use("../../stn/src/lib.hb");
 .{Channel, Window, send_header, send_message, await_channel, await_header, await_message, message, BUFFER_SERVER, BUFFER_CLIENT, WindowProps, WindowData} := @use("./lib.hb");
-.{new_surface, Color} := @use("../../render/src/lib.hb")
+.{Surface, Color} := @use("../../render/src/lib.hb")
 
 // ! in the future this should be safely handled
 channel := Channel.(0, 0)
@@ -26,7 +26,7 @@ new := fn(props: WindowProps): ?Window {
 		return null
 	}
 	log.info("client: recv windowdata\0")
-	surface := new_surface(windowdata.body.props.dimensions.x, windowdata.body.props.dimensions.y)
+	surface := Surface.new(windowdata.body.props.dimensions.x, windowdata.body.props.dimensions.y)
 	return .(windowdata.body, surface)
 }
 
diff --git a/sysdata/libraries/sunset_proto/src/server.hb b/sysdata/libraries/sunset_proto/src/server.hb
index 4dd16d9..0e08d9b 100644
--- a/sysdata/libraries/sunset_proto/src/server.hb
+++ b/sysdata/libraries/sunset_proto/src/server.hb
@@ -1,5 +1,5 @@
 .{math, log, string, random, buffer, memory} := @use("stn");
-.{Color, Surface, new_surface, put_surface, sync, put_rect, put_filled_rect, text, put_text, clear, white, black} := @use("lib:render");
+.{Color, Surface, text} := @use("lib:render");
 .{Channel, Window, WindowProps, WindowData, MessageHeader, BUFFER_SERVER, BUFFER_CLIENT, message, permissions, recv_header, recv_message, send_message, send_header, await_message} := @use("lib:sunset_proto")
 
 WindowServer := struct {
@@ -54,14 +54,14 @@ incoming := fn(): bool {
 			title_length := string.length(title)
 			deco_length := title_length * 10
 			// draw the window tab bar
-			put_filled_rect(surface, .(0, 0), .(data.props.dimensions.x + DECO_WIDTH + deco_length, DECO_HEIGHT_TOP), DECO_COLOUR)
+			surface.put_filled_rect(.(0, 0), .(data.props.dimensions.x + DECO_WIDTH + deco_length, DECO_HEIGHT_TOP), DECO_COLOUR)
 			// Draw the window tab
-			put_filled_rect(surface, .(0, 0), .(deco_length, DECO_HEIGHT_TOP - 1), DECO_COLOUR_DARKER)
+			surface.put_filled_rect(.(0, 0), .(deco_length, DECO_HEIGHT_TOP - 1), DECO_COLOUR_DARKER)
 
 			// Draw the outside box
-			put_rect(surface, .(0, 0), data.props.dimensions + .(DECO_WIDTH - 1, DECO_HEIGHT_TOP + DECO_HEIGHT_BOTTOM - 1), DECO_COLOUR)
+			surface.put_rect(.(0, 0), data.props.dimensions + .(DECO_WIDTH - 1, DECO_HEIGHT_TOP + DECO_HEIGHT_BOTTOM - 1), DECO_COLOUR)
 
-			put_text(surface, server.font, .(2, 1), .(0, 0, 0, 255), data.props.title)
+			surface.put_text(server.font, .(2, 1), .(0, 0, 0, 255), data.props.title)
 		}
 		server.windows[server.window_count] = .(data, surface)
 		server.window_count += 1
@@ -76,10 +76,7 @@ $DECO_COLOUR := Color.(100, 200, 255, 255)
 $DECO_COLOUR_DARKER := Color.(89, 57, 89, 255)
 
 new_window_decorations := fn(dimensions: math.Vec2(uint)): Surface {
-	return new_surface(
-		dimensions.x + DECO_WIDTH,
-		dimensions.y + DECO_HEIGHT_TOP + DECO_HEIGHT_BOTTOM,
-	)
+	return @inline(Surface.new, dimensions.x + DECO_WIDTH, dimensions.y + DECO_HEIGHT_TOP + DECO_HEIGHT_BOTTOM)
 }
 
 // ! compositor code. this currently disallows tearing.
@@ -106,8 +103,7 @@ collect_frames := fn(): void {
 		if ptr.header.kind != message.ack {
 			return
 		}
-		put_surface(
-			window.surface,
+		window.surface.put_surface(
 			Surface.(
 				ptr.body,
 				window.data.props.dimensions.x,
@@ -129,7 +125,7 @@ render_clients := fn(screen: Surface): void {
 			i += 1
 			continue
 		}
-		put_surface(screen, window.surface, window.data.props.position, false)
+		screen.put_surface(window.surface, window.data.props.position, false)
 		i += 1
 	}
 }
\ No newline at end of file
diff --git a/sysdata/programs/ablefetch/src/main.hb b/sysdata/programs/ablefetch/src/main.hb
index 7010775..4ce135d 100644
--- a/sysdata/programs/ablefetch/src/main.hb
+++ b/sysdata/programs/ablefetch/src/main.hb
@@ -21,15 +21,15 @@ main := fn(): void {
 	}
 
 	text_label := Label.new_label("kernel : akern 0.2.0\0", 300)
-	text_label.set_color(sunset.server.DECO_COLOUR, render.black)
+	text_label.set_color(sunset.server.DECO_COLOUR, render.BLACK)
 
 	text_label_2 := Label.new_label("os : ableos\0", 300)
-	text_label_2.set_color(sunset.server.DECO_COLOUR, render.black)
+	text_label_2.set_color(sunset.server.DECO_COLOUR, render.BLACK)
 	text_label_3 := Label.new_label("wm : sunset\0", 300)
-	text_label_3.set_color(sunset.server.DECO_COLOUR, render.black)
+	text_label_3.set_color(sunset.server.DECO_COLOUR, render.BLACK)
 
 	loop {
-		render.clear(window.surface, render.black)
+		render.clear(window.surface, render.BLACK)
 		// render.put_surface(window.surface, image, .(image.width + x % window.data.props.dimensions.x, 40), false)
 		pos := Vec2(uint).(1, 100)
 
diff --git a/sysdata/programs/render_example/src/examples/amogus.hb b/sysdata/programs/render_example/src/examples/amogus.hb
index eb68a10..d010bff 100644
--- a/sysdata/programs/render_example/src/examples/amogus.hb
+++ b/sysdata/programs/render_example/src/examples/amogus.hb
@@ -1,4 +1,4 @@
-render := @use("../../../../libraries/render/src/lib.hb")
+render := @use("lib:render")
 
 /* expected result:
    the impostor travels left and loops around the screen */
@@ -7,13 +7,13 @@ example := fn(): void {
 	screen := render.init(true)
 	x := 0
 	loop {
-		render.put_rect(screen, .(200 - x, 80), .(430, 380), render.red)
-		render.put_rect(screen, .(630 - x, 120), .(120, 300), render.red)
-		render.put_rect(screen, .(200 - x, 460), .(160, 270), render.red)
-		render.put_rect(screen, .(470 - x, 460), .(160, 270), render.red)
-		render.put_rect(screen, .(140 - x, 140), .(340, 250), render.cyan)
-		render.sync(screen)
-		render.clear(screen, render.black)
+		screen.clear(render.BLACK)
+		screen.put_rect(.(200 - x, 80), .(430, 380), render.RED)
+		screen.put_rect(.(630 - x, 120), .(120, 300), render.RED)
+		screen.put_rect(.(200 - x, 460), .(160, 270), render.RED)
+		screen.put_rect(.(470 - x, 460), .(160, 270), render.RED)
+		screen.put_rect(.(140 - x, 140), .(340, 250), render.CYAN)
+		screen.sync()
 		x += 1
 	}
 	return
diff --git a/sysdata/programs/render_example/src/examples/colors.hb b/sysdata/programs/render_example/src/examples/colors.hb
index 5560e9a..c1da5f2 100644
--- a/sysdata/programs/render_example/src/examples/colors.hb
+++ b/sysdata/programs/render_example/src/examples/colors.hb
@@ -1,4 +1,4 @@
-render := @use("../../../../libraries/render/src/lib.hb")
+render := @use("lib:render")
 
 /* expected result:
    the screen fades from cyan to green
@@ -7,12 +7,11 @@ render := @use("../../../../libraries/render/src/lib.hb")
 
 example := fn(): void {
 	screen := render.init(true)
-	color := render.light_cyan
+	color := render.LIGHT_CYAN
 	n := @as(u8, 1)
 	loop {
-		// ! dead code elimination bug
-		render.clear(screen, color)
-		render.sync(screen)
+		screen.clear(color)
+		screen.sync()
 		if color.b == 255 | color.b == 0 {
 			n = -n
 		}
diff --git a/sysdata/programs/render_example/src/examples/image.hb b/sysdata/programs/render_example/src/examples/image.hb
index d9f58e5..da9d402 100644
--- a/sysdata/programs/render_example/src/examples/image.hb
+++ b/sysdata/programs/render_example/src/examples/image.hb
@@ -1,13 +1,13 @@
-.{log, math, string} := @use("../../../../libraries/stn/src/lib.hb")
-render := @use("../../../../libraries/render/src/lib.hb")
+.{log, math, string} := @use("stn")
+render := @use("lib:render")
 
 /* expected result:
    a cute qoi image and a cute bmp image */
 
 example := fn(): void {
 	screen := render.init(true)
-	image_qoi := render.image.from(@bitcast(&@embed("../../../../assets/mini.qoi")))
-	image_bmp := render.image.from(@bitcast(&@embed("../../../../assets/mini.bmp")))
+	image_qoi := render.image.from(@bitcast(&@embed("sysdata:assets/mini.qoi")))
+	image_bmp := render.image.from(@bitcast(&@embed("sysdata:assets/mini.bmp")))
 
 	if image_qoi == null | image_bmp == null {
 		log.error("failed to load images for whatever reason\0")
@@ -16,10 +16,10 @@ example := fn(): void {
 
 	t := 0.0
 	loop {
-		render.clear(screen, render.black)
-		render.put_surface(screen, image_bmp, .(@bitcast(@fti(math.cos(t) * 100.0)) + (screen.width - image_bmp.width * 3) / 2, (screen.height - image_bmp.height) / 2), false)
-		render.put_surface(screen, image_qoi, .((screen.width + image_qoi.width) / 2, @bitcast(@fti(math.sin(t) * 100.0)) + (screen.height - image_qoi.height) / 2), false)
-		render.sync(screen)
+		screen.clear(render.BLACK)
+		screen.put_surface(image_bmp, .(@bitcast(@fti(math.cos(t) * 100.0)) + (screen.width - image_bmp.width * 3) / 2, (screen.height - image_bmp.height) / 2), false)
+		screen.put_surface(image_qoi, .((screen.width + image_qoi.width) / 2, @bitcast(@fti(math.sin(t) * 100.0)) + (screen.height - image_qoi.height) / 2), false)
+		screen.sync()
 		t += 0.02
 	}
 	return
diff --git a/sysdata/programs/render_example/src/examples/lines.hb b/sysdata/programs/render_example/src/examples/lines.hb
index 346ca9e..ba5a2df 100644
--- a/sysdata/programs/render_example/src/examples/lines.hb
+++ b/sysdata/programs/render_example/src/examples/lines.hb
@@ -1,5 +1,5 @@
-.{Vec2} := @use("../../../../libraries/stn/src/lib.hb").math
-render := @use("../../../../libraries/render/src/lib.hb")
+.{Vec2} := @use("stn:math")
+render := @use("lib:render")
 
 /* expected result:
    a 3d-looking set of blue lines
@@ -7,15 +7,15 @@ render := @use("../../../../libraries/render/src/lib.hb")
 
 example := fn(): void {
 	screen := render.init(true)
-	render.clear(screen, .(100, 50, 0, 255))
+	screen.clear(.(100, 50, 0, 255))
 	p0 := Vec2(uint).(0, 0)
 	p1 := Vec2(uint).(0, screen.height)
 	loop if p0.y >= screen.height break else {
-		render.put_line(screen, p0, p1, .(255, 180, 100, 255))
-		render.put_line(screen, .(screen.width, screen.height) - p0, .(screen.width, screen.height) - p1, .(255, 180, 100, 255))
+		screen.put_line(p0, p1, .(255, 180, 100, 255))
+		screen.put_line(.(screen.width, screen.height) - p0, .(screen.width, screen.height) - p1, .(255, 180, 100, 255))
 		p0.y += screen.height >> 6
 		p1.x += screen.width >> 6
 	}
-	render.sync(screen)
+	screen.sync()
 	return
 }
\ No newline at end of file
diff --git a/sysdata/programs/render_example/src/examples/mandelbrot.hb b/sysdata/programs/render_example/src/examples/mandelbrot.hb
index db1b054..3cfd845 100644
--- a/sysdata/programs/render_example/src/examples/mandelbrot.hb
+++ b/sysdata/programs/render_example/src/examples/mandelbrot.hb
@@ -46,22 +46,22 @@ 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
+// $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
+$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 := 10000
+$MAX_MAX_ITERATION := 30000000
 
-$USE_SUNSET := true
+$USE_SUNSET := false
 
 $COLOUR_R := 200
 $COLOUR_G := 100
@@ -71,7 +71,7 @@ $COLOUR_B := 255
 // $COLOUR_G := 255
 // $COLOUR_B := 255
 
-// $INTERIOR_COLOUR := render.white
+// $INTERIOR_COLOUR := render.WHITE
 $INTERIOR_COLOUR := render.Color.{r: COLOUR_R, g: COLOUR_G, b: COLOUR_B, a: 255}
 
 example := fn(): void {
@@ -88,7 +88,7 @@ example := fn(): void {
 	} else {
 		screen = render.init(false)
 	}
-	render.clear(screen, INTERIOR_COLOUR)
+	screen.clear(INTERIOR_COLOUR)
 
 	max_iteration := 0
 	prev_max_iteration := 0
@@ -138,13 +138,13 @@ example := fn(): void {
 						b: @intcast(@fti(smooth_value * COLOUR_B)),
 						a: 0,
 					}
-					render.put_pixel(screen, .(px, py), colour)
+					screen.put_pixel(.(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))
+					screen.put_hline(py, px, px + 5, .(0, 0, 0, 0))
 					px += 5
 				} else {
 					px += 1
@@ -160,9 +160,4 @@ example := fn(): void {
 			_ = 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/examples/orbit.hb b/sysdata/programs/render_example/src/examples/orbit.hb
index b83d1d4..519f44c 100644
--- a/sysdata/programs/render_example/src/examples/orbit.hb
+++ b/sysdata/programs/render_example/src/examples/orbit.hb
@@ -1,8 +1,8 @@
-.{Vec2, sin, cos, PI} := @use("../../../../libraries/stn/src/lib.hb").math
-render := @use("../../../../libraries/render/src/lib.hb")
+.{Vec2, sin, cos, PI} := @use("stn:math")
+render := @use("lib:render")
 
-able_bmp := @embed("../../../../assets/able.bmp")
-mini_bmp := @embed("../../../../assets/mini.bmp")
+able_bmp := @embed("sysdata:assets/able.bmp")
+mini_bmp := @embed("sysdata:assets/mini.bmp")
 
 /* expected result:
    two textured circles rotating
@@ -22,12 +22,12 @@ example := fn(): void {
 	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(@fti(sin(angle) * 256)), screen.height / 2 + @intcast(@fti(cos(angle) * 256))), able.width / 2 - 1)
-		render.put_textured_circle(screen, mini, .(mini.width / 2, mini.height / 2), .(screen.width / 2 + @intcast(@fti(sin(angle + PI) * 256)), screen.height / 2 + @intcast(@fti(cos(angle + PI) * 256))), mini.width / 2 - 1)
-		render.sync(screen)
+		screen.clear(render.BLACK)
+		screen.put_filled_circle(.(screen.width / 2, screen.height / 2), 128, render.LIGHT_YELLOW)
+		screen.put_circle(.(screen.width / 2, screen.height / 2), 256, render.LIGHT_BLUE)
+		screen.put_textured_circle(able, .(able.width / 2, able.height / 2), .(screen.width / 2 + @intcast(@fti(sin(angle) * 256)), screen.height / 2 + @intcast(@fti(cos(angle) * 256))), able.width / 2 - 1)
+		screen.put_textured_circle(mini, .(mini.width / 2, mini.height / 2), .(screen.width / 2 + @intcast(@fti(sin(angle + PI) * 256)), screen.height / 2 + @intcast(@fti(cos(angle + PI) * 256))), mini.width / 2 - 1)
+		screen.sync()
 
 		angle += 0.01
 	}
diff --git a/sysdata/programs/render_example/src/examples/random.hb b/sysdata/programs/render_example/src/examples/random.hb
index 6710c10..d79df44 100644
--- a/sysdata/programs/render_example/src/examples/random.hb
+++ b/sysdata/programs/render_example/src/examples/random.hb
@@ -3,14 +3,14 @@ render := @use("../../../../libraries/render/src/lib.hb")
 
 example := fn(): void {
 	screen := render.init(false)
-	render.clear(screen, render.black)
+	screen.clear(render.BLACK)
 	loop {
 		x := random.range(uint, 0, screen.width)
 		y := random.range(uint, 0, screen.height)
 		r := random.range(u8, 0, 255)
 		g := random.range(u8, 0, 75)
 		b := random.range(u8, 0, 155)
-		render.put_pixel(screen, .(x, y), .(b, g, r, 255))
+		screen.put_pixel(.(x, y), .(b, g, r, 255))
 	}
 	return
 }
\ No newline at end of file
diff --git a/sysdata/programs/render_example/src/examples/square.hb b/sysdata/programs/render_example/src/examples/square.hb
index b66723d..1105b3a 100644
--- a/sysdata/programs/render_example/src/examples/square.hb
+++ b/sysdata/programs/render_example/src/examples/square.hb
@@ -1,6 +1,5 @@
-.{Vec2} := @use("../../../../libraries/stn/src/lib.hb").math;
-.{random} := @use("../../../../libraries/stn/src/lib.hb")
-render := @use("../../../../libraries/render/src/lib.hb")
+.{math: .{Vec2}, random} := @use("stn")
+render := @use("lib:render")
 
 /* expected result:
    a square that changes colour bounces around the screen */
@@ -12,9 +11,9 @@ example := fn(): void {
 	pos := Vec2(uint).((screen.width - side) / 2, (screen.height - side) / 2)
 	color := random.any(render.Color)
 	loop {
-		render.put_filled_rect(screen, pos, .(side, side), color)
-		render.sync(screen)
-		render.clear(screen, render.black)
+		screen.put_filled_rect(pos, .(side, side), color)
+		screen.sync()
+		screen.clear(render.BLACK)
 
 		if pos.x == 0 | pos.x == screen.width - side {
 			vel.x = -vel.x
diff --git a/sysdata/programs/render_example/src/examples/surface.hb b/sysdata/programs/render_example/src/examples/surface.hb
index 5a3eefc..cc3873f 100644
--- a/sysdata/programs/render_example/src/examples/surface.hb
+++ b/sysdata/programs/render_example/src/examples/surface.hb
@@ -1,6 +1,5 @@
-.{Vec2} := @use("../../../../libraries/stn/src/lib.hb").math;
-.{random} := @use("../../../../libraries/stn/src/lib.hb")
-render := @use("../../../../libraries/render/src/lib.hb")
+.{math: .{Vec2}, random} := @use("stn")
+render := @use("lib:render")
 
 /* expected result:
    bouncing gradient square inside coloured bouncing box inside black screen */
@@ -8,7 +7,7 @@ render := @use("../../../../libraries/render/src/lib.hb")
 example := fn(): void {
 	screen := render.init(true)
 
-	image := render.new_surface(screen.width / 3, screen.height / 3)
+	image := render.Surface.new(screen.width / 3, screen.height / 3)
 	vel := Vec2(int).(-1, -1)
 	pos := Vec2(uint).(100, 100)
 	side := image.width / 8
@@ -17,14 +16,14 @@ example := fn(): void {
 	color := random.any(render.Color)
 	target_color := random.any(render.Color)
 	loop {
-		render.clear(screen, render.black)
-		render.put_filled_rect(image, pos_inner, .(side, side), color)
-		render.put_rect(image, pos_inner, .(side, side), render.black)
-		render.put_rect(image, .(0, 0), .(image.width - 1, image.height - 1), color)
+		screen.clear(render.BLACK)
+		image.put_filled_rect(pos_inner, .(side, side), color)
+		image.put_rect(pos_inner, .(side, side), render.BLACK)
+		image.put_rect(.(0, 0), .(image.width - 1, image.height - 1), color)
 
-		render.put_surface(screen, image, pos, false)
-		render.put_rect(image, pos_inner, .(side, side), color)
-		render.sync(screen)
+		screen.put_surface(image, pos, false)
+		image.put_rect(pos_inner, .(side, side), color)
+		screen.sync()
 
 		if pos_inner.x == 0 | pos_inner.x == image.width - side {
 			vel_inner.x = -vel_inner.x
diff --git a/sysdata/programs/render_example/src/examples/tactical_screen.hb b/sysdata/programs/render_example/src/examples/tactical_screen.hb
index b15792a..4471d80 100644
--- a/sysdata/programs/render_example/src/examples/tactical_screen.hb
+++ b/sysdata/programs/render_example/src/examples/tactical_screen.hb
@@ -1,7 +1,5 @@
-render := @use("../../../../libraries/render/src/lib.hb");
-.{math, random} := @use("../../../../libraries/stn/src/lib.hb")
-Vec2 := math.Vec2
-
+.{math: .{Vec2}, random} := @use("stn")
+render := @use("lib:render")
 /* expected result:
    a grid of green lines scrolling from the left top corner to the right bottom one
    with a "target" randomly apperaing in one of them and a "seeker" "catching" it */
@@ -33,32 +31,32 @@ example := fn(): void {
 	seeker := Vec2(uint).(random.range(uint, 0, range.x), random.range(uint, 0, range.y))
 
 	loop {
-		render.clear(screen, render.black)
+		screen.clear(render.BLACK)
 
 		target_pixel_coord := target * .(@bitcast(cell_size), @bitcast(cell_size)) + .(scroll, scroll)
-		render.put_trirect(screen, target_pixel_coord, .(@bitcast(cell_size), @bitcast(cell_size)), render.red, render.light_red)
+		screen.put_trirect(target_pixel_coord, .(@bitcast(cell_size), @bitcast(cell_size)), render.RED, render.LIGHT_RED)
 
-		render.put_hline(screen, target_pixel_coord.y + halfcell, target_pixel_coord.x - octcell, target_pixel_coord.x - sevenoctcell, render.light_red)
-		render.put_hline(screen, target_pixel_coord.y + halfcell, target_pixel_coord.x + cell_size + octcell, target_pixel_coord.x + cell_size + sevenoctcell, render.light_red)
-		render.put_vline(screen, target_pixel_coord.x + halfcell, target_pixel_coord.y - octcell, target_pixel_coord.y - sevenoctcell, render.light_red)
-		render.put_vline(screen, target_pixel_coord.x + halfcell, target_pixel_coord.y + cell_size + octcell, target_pixel_coord.y + cell_size + sevenoctcell, render.light_red)
+		screen.put_hline(target_pixel_coord.y + halfcell, target_pixel_coord.x - octcell, target_pixel_coord.x - sevenoctcell, render.LIGHT_RED)
+		screen.put_hline(target_pixel_coord.y + halfcell, target_pixel_coord.x + cell_size + octcell, target_pixel_coord.x + cell_size + sevenoctcell, render.LIGHT_RED)
+		screen.put_vline(target_pixel_coord.x + halfcell, target_pixel_coord.y - octcell, target_pixel_coord.y - sevenoctcell, render.LIGHT_RED)
+		screen.put_vline(target_pixel_coord.x + halfcell, target_pixel_coord.y + cell_size + octcell, target_pixel_coord.y + cell_size + sevenoctcell, render.LIGHT_RED)
 
 		x := scroll
 		loop if x > width break else {
-			render.put_vline(screen, x, 0, height, .(0, 127, 0, 127))
+			screen.put_vline(x, 0, height, .(0, 127, 0, 127))
 			x += cell_size
 		}
 
 		y := scroll
 		loop if y > height break else {
-			render.put_hline(screen, y, 0, width, .(0, 127, 0, 127))
+			screen.put_hline(y, 0, width, .(0, 127, 0, 127))
 			y += cell_size
 		}
 
-		render.put_hline(screen, seeker.y * cell_size + halfcell + scroll, 0, width, render.blue)
-		render.put_vline(screen, seeker.x * cell_size + halfcell + scroll, 0, height, render.blue)
+		screen.put_hline(seeker.y * cell_size + halfcell + scroll, 0, width, render.BLUE)
+		screen.put_vline(seeker.x * cell_size + halfcell + scroll, 0, height, render.BLUE)
 
-		render.sync(screen)
+		screen.sync()
 
 		if seeker.x < target.x {
 			seeker.x += 1
diff --git a/sysdata/programs/render_example/src/examples/text.hb b/sysdata/programs/render_example/src/examples/text.hb
index a817407..0e89eb4 100644
--- a/sysdata/programs/render_example/src/examples/text.hb
+++ b/sysdata/programs/render_example/src/examples/text.hb
@@ -1,5 +1,5 @@
-.{memory, log, string, math} := @use("../../../../libraries/stn/src/lib.hb")
-render := @use("../../../../libraries/render/src/lib.hb")
+.{memory, log, string, math} := @use("stn")
+render := @use("lib:render")
 
 /* expected result: pretty decent notepad app
    slightly jank
@@ -13,8 +13,8 @@ render := @use("../../../../libraries/render/src/lib.hb")
    - shift key support
 */
 
-psf := @embed("../../../../assets/consolefonts/tamsyn/10x20r.psf")
-img := @embed("../../../../assets/wallpaper.qoi")
+psf := @embed("sysdata:assets/consolefonts/tamsyn/10x20r.psf")
+img := @embed("sysdata:assets/wallpaper.qoi")
 
 is_shift_pressed := false
 is_ctrl_pressed := false
@@ -28,7 +28,7 @@ $down_arrow := 0x50
 
 example := fn(): void {
 	screen := render.init(true)
-	window := render.new_surface(600, 300)
+	window := render.Surface.new(600, 300)
 	font := render.text.font_from_psf2(@bitcast(&psf), false)
 	wallpaper := render.image.from(@bitcast(&img))
 
@@ -137,16 +137,16 @@ handle_extended_key := fn(scancode: u8, cursor: ^u8, bottom: ^u8, font: render.t
 padding := 3 * @sizeof(render.Color)
 
 draw_window := fn(window: render.Surface, font: render.text.Font, buf: ^u8, cursor: ^u8): void {
-	render.clear(window, .(0x88, 0xF4, 0xFC, 0x0))
+	window.clear(.(0x88, 0xF4, 0xFC, 0x0))
 	line := font.height + padding - 1
-	render.put_rect(window, .(0, 0), .(window.width - 1, window.height - 1), render.black)
+	window.put_rect(.(0, 0), .(window.width - 1, window.height - 1), render.BLACK)
 
 	loop if line >= window.height break else {
-		render.put_hline(window, line, padding, window.width - padding, render.yellow)
+		window.put_hline(line, padding, window.width - padding, render.YELLOW)
 		line += font.height
 	}
 
-	render.put_text(window, font, .(padding, padding), render.black, buf)
+	window.put_text(font, .(padding, padding), render.BLACK, buf)
 
 	cursor_offset := cursor - buf
 
@@ -168,13 +168,13 @@ draw_window := fn(window: render.Surface, font: render.text.Font, buf: ^u8, curs
 		i += 1
 	}
 
-	render.put_rect(window, .(x_pos, y_pos), .(1, font.height - 1), render.black)
+	window.put_rect(.(x_pos, y_pos), .(1, font.height - 1), render.BLACK)
 }
 
 draw_screen := fn(screen: render.Surface, window: render.Surface, wallpaper: render.Surface): void {
-	render.put_surface(screen, wallpaper, .(0, 0), false)
-	render.put_surface(screen, window, .(100, 100), false)
-	render.sync(screen)
+	screen.put_surface(wallpaper, .(0, 0), false)
+	screen.put_surface(window, .(100, 100), false)
+	screen.sync()
 }
 
 handle_char := fn(char: u8, cursor: ^u8, bottom: ^u8): ^u8 {
diff --git a/sysdata/programs/render_example/src/main.hb b/sysdata/programs/render_example/src/main.hb
index 5273ce2..acb3c00 100644
--- a/sysdata/programs/render_example/src/main.hb
+++ b/sysdata/programs/render_example/src/main.hb
@@ -1 +1 @@
-.{example: main} := @use("./examples/mandelbrot.hb")
\ No newline at end of file
+.{example: main} := @use("./examples/amogus.hb")
\ No newline at end of file
diff --git a/sysdata/programs/sunset_server/src/main.hb b/sysdata/programs/sunset_server/src/main.hb
index 68ba597..d456beb 100644
--- a/sysdata/programs/sunset_server/src/main.hb
+++ b/sysdata/programs/sunset_server/src/main.hb
@@ -18,7 +18,7 @@ main := fn(): int {
 	}
 
 	screen := render.init(true)
-	render.clear(screen, render.black)
+	screen.clear(render.BLACK)
 	font := @unwrap(render.text.font_from_psf2(@bitcast(&psf), false))
 
 	wallpaper := render.image.from(@bitcast(&img))
@@ -31,7 +31,7 @@ main := fn(): int {
 	mouse_y := 100
 
 	text_label := Label.new_label("\0", 1024)
-	text_label.set_color(sunset.server.DECO_COLOUR, render.black)
+	text_label.set_color(sunset.server.DECO_COLOUR, render.BLACK)
 
 	loop {
 		mouse_event := intouch.recieve_mouse_event()
@@ -71,10 +71,10 @@ main := fn(): int {
 			}
 		}
 		{
-			render.clear(screen, render.black)
-			render.put_surface(screen, wallpaper, .(0, 0), false)
+			screen.clear(render.BLACK)
+			screen.put_surface(wallpaper, .(0, 0), false)
 
-			render.put_rect(screen, .(0, 0), .(screen.width - 1, screen.height - 1), sunset.server.DECO_COLOUR)
+			screen.put_rect(.(0, 0), .(screen.width - 1, screen.height - 1), sunset.server.DECO_COLOUR)
 		}
 
 		if sunset.server.incoming() {
@@ -87,16 +87,16 @@ main := fn(): int {
 			omnibar_height := 21
 			pos := Vec2(uint).(1, screen.height - omnibar_height)
 			render_label_to_surface(screen, text_label, font, pos)
-			render.put_rect(screen, .(0, screen.height - 21), .(screen.width - 1, 20), sunset.server.DECO_COLOUR)
+			screen.put_rect(.(0, screen.height - 21), .(screen.width - 1, 20), sunset.server.DECO_COLOUR)
 		}
 
 		// Mouse cursor
 		{
-			render.put_filled_circle(screen, .(mouse_x, mouse_y), 10, sunset.server.DECO_COLOUR_DARKER)
-			render.put_circle(screen, .(mouse_x, mouse_y), 10, sunset.server.DECO_COLOUR)
+			screen.put_filled_circle(.(mouse_x, mouse_y), 10, sunset.server.DECO_COLOUR_DARKER)
+			screen.put_circle(.(mouse_x, mouse_y), 10, sunset.server.DECO_COLOUR)
 		}
 
-		render.sync(screen)
+		screen.sync()
 	}
 
 	return 0
diff --git a/sysdata/system_config.toml b/sysdata/system_config.toml
index 8df697f..a811525 100644
--- a/sysdata/system_config.toml
+++ b/sysdata/system_config.toml
@@ -25,11 +25,11 @@ resolution = "1024x768x24"
 [boot.limine.ableos.modules.render_example]
 path = "boot:///render_example.hbf"
 
-[boot.limine.ableos.modules.sunset_server]
-path = "boot:///sunset_server.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"
+# [boot.limine.ableos.modules.ps2_mouse_driver]
+# path = "boot:///ps2_mouse_driver.hbf"
 
 # [boot.limine.ableos.modules.ps2_keyboard_driver]
 # path = "boot:///ps2_keyboard_driver.hbf"

From 5b3a97e580ac357beee0b9d7d415dd71a5fd07b7 Mon Sep 17 00:00:00 2001
From: koniifer <koniifer@proton.me>
Date: Sat, 14 Dec 2024 19:43:33 +0000
Subject: [PATCH 2/6] fixed struct method things

---
 Cargo.lock                                                | 6 +++---
 .../programs/render_example/src/examples/mandelbrot.hb    | 2 +-
 sysdata/programs/render_example/src/main.hb               | 2 +-
 sysdata/system_config.toml                                | 8 ++++----
 4 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index 469feb6..d181906 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -213,12 +213,12 @@ dependencies = [
 [[package]]
 name = "hbbytecode"
 version = "0.1.0"
-source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#91e35b72eeab9c230d52ec8636faf1dc0f96554a"
+source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#dc96c8b10ae85af7a11bd1e8ca2cd29e2c42a033"
 
 [[package]]
 name = "hblang"
 version = "0.1.0"
-source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#91e35b72eeab9c230d52ec8636faf1dc0f96554a"
+source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#dc96c8b10ae85af7a11bd1e8ca2cd29e2c42a033"
 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#91e35b72eeab9c230d52ec8636faf1dc0f96554a"
+source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#dc96c8b10ae85af7a11bd1e8ca2cd29e2c42a033"
 dependencies = [
  "hbbytecode",
 ]
diff --git a/sysdata/programs/render_example/src/examples/mandelbrot.hb b/sysdata/programs/render_example/src/examples/mandelbrot.hb
index 3cfd845..391bcc1 100644
--- a/sysdata/programs/render_example/src/examples/mandelbrot.hb
+++ b/sysdata/programs/render_example/src/examples/mandelbrot.hb
@@ -61,7 +61,7 @@ $Y_MAX := 0.306
 // if you use the mandelbrot it looks best under 30
 $MAX_MAX_ITERATION := 30000000
 
-$USE_SUNSET := false
+$USE_SUNSET := true
 
 $COLOUR_R := 200
 $COLOUR_G := 100
diff --git a/sysdata/programs/render_example/src/main.hb b/sysdata/programs/render_example/src/main.hb
index acb3c00..5273ce2 100644
--- a/sysdata/programs/render_example/src/main.hb
+++ b/sysdata/programs/render_example/src/main.hb
@@ -1 +1 @@
-.{example: main} := @use("./examples/amogus.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 a811525..8df697f 100644
--- a/sysdata/system_config.toml
+++ b/sysdata/system_config.toml
@@ -25,11 +25,11 @@ resolution = "1024x768x24"
 [boot.limine.ableos.modules.render_example]
 path = "boot:///render_example.hbf"
 
-# [boot.limine.ableos.modules.sunset_server]
-# path = "boot:///sunset_server.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"
+[boot.limine.ableos.modules.ps2_mouse_driver]
+path = "boot:///ps2_mouse_driver.hbf"
 
 # [boot.limine.ableos.modules.ps2_keyboard_driver]
 # path = "boot:///ps2_keyboard_driver.hbf"

From 642b0b74b5d9f79280cc1d2663d6e172e7d2a802 Mon Sep 17 00:00:00 2001
From: koniifer <koniifer@proton.me>
Date: Sun, 15 Dec 2024 22:05:06 +0000
Subject: [PATCH 3/6] cooler mandelbrot

---
 Cargo.lock                                    |  14 +-
 .../render_example/src/examples/mandelbrot.hb | 238 +++++++++---------
 sysdata/system_config.toml                    |   8 +-
 3 files changed, 135 insertions(+), 125 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index d181906..5ee0f13 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -88,18 +88,18 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
 
 [[package]]
 name = "crossbeam-queue"
-version = "0.3.11"
+version = "0.3.12"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "df0346b5d5e76ac2fe4e327c5fd1118d6be7c51dfb18f9b7922923f287471e35"
+checksum = "0f58bbc28f91df819d0aa2a2c00cd19754769c2fad90579b3592b1c9ba7a3115"
 dependencies = [
  "crossbeam-utils",
 ]
 
 [[package]]
 name = "crossbeam-utils"
-version = "0.8.20"
+version = "0.8.21"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80"
+checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
 
 [[package]]
 name = "derive_more"
@@ -213,12 +213,12 @@ dependencies = [
 [[package]]
 name = "hbbytecode"
 version = "0.1.0"
-source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#dc96c8b10ae85af7a11bd1e8ca2cd29e2c42a033"
+source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#9f43e3bb925534f613cb2089df6e5fe315fc851a"
 
 [[package]]
 name = "hblang"
 version = "0.1.0"
-source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#dc96c8b10ae85af7a11bd1e8ca2cd29e2c42a033"
+source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#9f43e3bb925534f613cb2089df6e5fe315fc851a"
 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#dc96c8b10ae85af7a11bd1e8ca2cd29e2c42a033"
+source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#9f43e3bb925534f613cb2089df6e5fe315fc851a"
 dependencies = [
  "hbbytecode",
 ]
diff --git a/sysdata/programs/render_example/src/examples/mandelbrot.hb b/sysdata/programs/render_example/src/examples/mandelbrot.hb
index 391bcc1..15c5548 100644
--- a/sysdata/programs/render_example/src/examples/mandelbrot.hb
+++ b/sysdata/programs/render_example/src/examples/mandelbrot.hb
@@ -1,45 +1,66 @@
-// 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
-// }
+ln_f64 := fn(x: f64): f64 {
+	if x <= 0.0 return -100000000000000000000000.0
+	if x == 1.0 return 0.0
+	if x == E return 1.0
 
-// 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
-// }
+	scale := @as(f64, 0.0)
+	scaled_x := x
 
-// 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
-// }
+	if scaled_x > 2.0 {
+		loop if scaled_x <= 2.0 break else {
+			scaled_x = scaled_x / E
+			scale += 1.0
+		}
+	} else if scaled_x < 1.0 {
+		loop if scaled_x >= 1.0 {
+			scaled_x = scaled_x * E
+			scale -= 1.0
+		}
+	}
+
+	guess := (scaled_x - 1.0) / (scaled_x + 1.0)
+
+	max_iter := 30
+	i := 0
+	loop if i == max_iter break else {
+		exp_g := exp_f64(guess)
+		f := exp_g - scaled_x
+		f_prime := exp_g
+
+		delta := f / (f_prime * (1.0 - 0.5 * f * f_prime / (f_prime * f_prime)))
+
+		guess = guess - delta
+
+		if abs_f64(delta) < 0.0000000001 break
+		i += 1
+	}
+
+	return guess + scale
+}
+
+exp_f64 := fn(x: f64): f64 {
+	result := @as(f64, 1.0)
+	term := @as(f64, 1.0)
+	n := @as(int, 1)
+
+	loop if n == 20 break else {
+		term = term * x / @itf(n)
+		result += term
+
+		if abs_f64(term) < 0.0000000001 break
+		n += 1
+	}
+
+	return result
+}
+
+abs_f64 := fn(x: f64): f64 {
+	if x < 0 return -x else return x
+}
+
+lerp_f64 := fn(v0: f64, v1: f64, t: f64): f64 {
+	return v0 + t * (v1 - v0)
+}
 
 render := @use("lib:render")
 sunset := @use("lib:sunset_proto");
@@ -57,22 +78,21 @@ $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 := 30000000
+$MAX_ITERATION := 300
 
-$USE_SUNSET := true
+$USE_SUNSET := false
 
 $COLOUR_R := 200
 $COLOUR_G := 100
 $COLOUR_B := 255
 
-// $COLOUR_R := 255
-// $COLOUR_G := 255
-// $COLOUR_B := 255
+$LOG_2 := 0.693147180559945309417232121458176568
+$E := 2.71828182845904523536028747135266250
 
-// $INTERIOR_COLOUR := render.WHITE
-$INTERIOR_COLOUR := render.Color.{r: COLOUR_R, g: COLOUR_G, b: COLOUR_B, a: 255}
+$INTERIOR_COLOUR := render.BLACK
+
+palette := [render.Color].(render.RED, render.YELLOW, render.GREEN, render.CYAN, render.BLUE, render.MAGENTA)
+$LEN_PALETTE := @sizeof(@TypeOf(palette)) / @sizeof(render.Color)
 
 example := fn(): void {
 	screen := @as(render.Surface, idk)
@@ -90,74 +110,64 @@ example := fn(): void {
 	}
 	screen.clear(INTERIOR_COLOUR)
 
-	max_iteration := 0
-	prev_max_iteration := 0
+	x_scale := @as(f64, X_MAX - X_MIN) / @itf(@bitcast(screen.width))
+	y_scale := @as(f64, Y_MAX - Y_MIN) / @itf(@bitcast(screen.height))
 
-	x_scale := (X_MAX - X_MIN) / @floatcast(@itf(@bitcast(screen.width)))
-	y_scale := (Y_MAX - Y_MIN) / @floatcast(@itf(@bitcast(screen.height)))
+	py := 0
+	loop if py == screen.height break else {
+		px := 0
+		loop if px >= screen.width break else {
+			x0 := @as(f64, X_MIN) + @itf(@bitcast(px)) * x_scale
+			y0 := @as(f64, Y_MIN) + @itf(@bitcast(py)) * y_scale
 
-	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,
-					}
-					screen.put_pixel(.(px, py), colour)
-				}
-				// faster
-				if iteration >= max_iteration {
-					px += 2
-				} else if iteration < 5 {
-					screen.put_hline(py, px, px + 5, .(0, 0, 0, 0))
-					px += 5
-				} else {
-					px += 1
-				}
-				// slower but more slightly more accurate
-				// px += 1
+			q := (x0 - 0.25) * (x0 - 0.25) + y0 * y0
+			if q * (q + x0 - 0.25) <= 0.25 * y0 * y0 {
+				px += 1
+				continue
 			}
-			py += 1
-		}
-		prev_max_iteration = max_iteration
-		max_iteration += 5
-		if USE_SUNSET {
-			_ = sunset.client.send_frame(window)
+
+			if (x0 + 1.0) * (x0 + 1.0) + y0 * y0 <= 0.0625 {
+				px += 1
+				continue
+			}
+
+			x := @as(f64, 0.0)
+			y := @as(f64, 0.0)
+			iteration := 0
+
+			loop if x * x + y * y > @itf(1 << 16) | iteration == MAX_ITERATION break else {
+				x_temp := x * x - y * y + x0
+				y = 2 * x * y + y0
+				x = x_temp
+				iteration += 1
+			}
+
+			c := *screen.indexptr(px, py)
+			if c.r != INTERIOR_COLOUR.r | c.b != INTERIOR_COLOUR.b | c.g != INTERIOR_COLOUR.g {
+				px += 1
+				continue
+			}
+			if iteration < MAX_ITERATION {
+				log_zn := ln_f64(x * x + y * y) / 2.0
+				nu := ln_f64(log_zn / LOG_2) / LOG_2
+				smoothed := @itf(@bitcast(iteration + 1)) - nu
+				smoothed_int := @fti(smoothed)
+				normalised := smoothed - @itf(smoothed_int)
+				colour0 := palette[@bitcast(smoothed_int) % LEN_PALETTE]
+				colour1 := palette[@bitcast(smoothed_int + 1) % LEN_PALETTE]
+				colour := render.Color.{
+					r: @intcast(@fti(lerp_f64(@itf(@intcast(colour0.r)), @itf(@intcast(colour1.r)), normalised))),
+					g: @intcast(@fti(lerp_f64(@itf(@intcast(colour0.g)), @itf(@intcast(colour1.g)), normalised))),
+					b: @intcast(@fti(lerp_f64(@itf(@intcast(colour0.b)), @itf(@intcast(colour1.b)), normalised))),
+					a: 0,
+				}
+				screen.put_pixel(.(px, py), colour)
+			}
+			px += 1
 		}
+		py += 1
+	}
+	if USE_SUNSET loop {
+		_ = sunset.client.send_frame(window)
 	}
 }
\ No newline at end of file
diff --git a/sysdata/system_config.toml b/sysdata/system_config.toml
index 8df697f..a811525 100644
--- a/sysdata/system_config.toml
+++ b/sysdata/system_config.toml
@@ -25,11 +25,11 @@ resolution = "1024x768x24"
 [boot.limine.ableos.modules.render_example]
 path = "boot:///render_example.hbf"
 
-[boot.limine.ableos.modules.sunset_server]
-path = "boot:///sunset_server.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"
+# [boot.limine.ableos.modules.ps2_mouse_driver]
+# path = "boot:///ps2_mouse_driver.hbf"
 
 # [boot.limine.ableos.modules.ps2_keyboard_driver]
 # path = "boot:///ps2_keyboard_driver.hbf"

From 55c8d9b8b258c104d35fc1ee12ede734bd577a9c Mon Sep 17 00:00:00 2001
From: koniifer <koniifer@proton.me>
Date: Sun, 15 Dec 2024 22:27:09 +0000
Subject: [PATCH 4/6] hblang update

---
 Cargo.lock | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index 5ee0f13..af27ea7 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -213,12 +213,12 @@ dependencies = [
 [[package]]
 name = "hbbytecode"
 version = "0.1.0"
-source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#9f43e3bb925534f613cb2089df6e5fe315fc851a"
+source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#8138d6664fb6983b10192f5a982a8bf5ec327287"
 
 [[package]]
 name = "hblang"
 version = "0.1.0"
-source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#9f43e3bb925534f613cb2089df6e5fe315fc851a"
+source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#8138d6664fb6983b10192f5a982a8bf5ec327287"
 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#9f43e3bb925534f613cb2089df6e5fe315fc851a"
+source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#8138d6664fb6983b10192f5a982a8bf5ec327287"
 dependencies = [
  "hbbytecode",
 ]

From 6e3fea0713fd7beb7f2d77c60a321f006a70a502 Mon Sep 17 00:00:00 2001
From: koniifer <koniifer@proton.me>
Date: Mon, 16 Dec 2024 01:06:55 +0000
Subject: [PATCH 5/6] fiddling and move some stuff to stn.math

---
 .../holeybytes/kernel_services/mem_serve.rs   |  15 ++-
 sysdata/libraries/stn/src/math.hb             | 108 ++++++++++++++--
 sysdata/libraries/stn/src/memory.hb           |  14 +-
 .../render_example/src/examples/mandelbrot.hb | 120 +++---------------
 sysdata/system_config.toml                    |   1 +
 5 files changed, 132 insertions(+), 126 deletions(-)

diff --git a/kernel/src/holeybytes/kernel_services/mem_serve.rs b/kernel/src/holeybytes/kernel_services/mem_serve.rs
index a2cb42a..47fa95b 100644
--- a/kernel/src/holeybytes/kernel_services/mem_serve.rs
+++ b/kernel/src/holeybytes/kernel_services/mem_serve.rs
@@ -96,18 +96,19 @@ pub fn memory_msg_handler(
             log::debug!(" {} pages", page_count);
         }
         4 => unsafe {
-            let count = u32::from_le_bytes(msg_vec[1..5].try_into().unwrap_unchecked()) as usize;
-            let src = u64::from_le_bytes(msg_vec[5..13].try_into().unwrap_unchecked()) as *const u8;
-            let dest = u64::from_le_bytes(msg_vec[13..21].try_into().unwrap_unchecked()) as *mut u8;
+            let count = u64::from_le_bytes(msg_vec[1..9].try_into().unwrap_unchecked()) as usize;
+            let src = u64::from_le_bytes(msg_vec[9..17].try_into().unwrap_unchecked()) as *const u8;
+            let dest = u64::from_le_bytes(msg_vec[17..25].try_into().unwrap_unchecked()) as *mut u8;
             debug_assert!(src.addr() & 0xFFFF000000000000 != 0);
             debug_assert!(dest.addr() & 0xFFFF000000000000 != 0);
             src.copy_to_nonoverlapping(dest, count);
         },
         5 => unsafe {
-            let count = u32::from_le_bytes(msg_vec[1..5].try_into().unwrap_unchecked()) as usize;
-            let size = u32::from_le_bytes(msg_vec[5..9].try_into().unwrap_unchecked()) as usize;
-            let src = u64::from_le_bytes(msg_vec[9..17].try_into().unwrap_unchecked()) as *const u8;
-            let dest = u64::from_le_bytes(msg_vec[17..25].try_into().unwrap_unchecked()) as *mut u8;
+            let count = u64::from_le_bytes(msg_vec[1..9].try_into().unwrap_unchecked()) as usize;
+            let size = u64::from_le_bytes(msg_vec[9..17].try_into().unwrap_unchecked()) as usize;
+            let src =
+                u64::from_le_bytes(msg_vec[17..25].try_into().unwrap_unchecked()) as *const u8;
+            let dest = u64::from_le_bytes(msg_vec[25..33].try_into().unwrap_unchecked()) as *mut u8;
             debug_assert!(src.addr() & 0xFFFF000000000000 != 0);
             debug_assert!(dest.addr() & 0xFFFF000000000000 != 0);
             memset(dest, src, count, size);
diff --git a/sysdata/libraries/stn/src/math.hb b/sysdata/libraries/stn/src/math.hb
index b868cd8..d8a9b0e 100644
--- a/sysdata/libraries/stn/src/math.hb
+++ b/sysdata/libraries/stn/src/math.hb
@@ -1,24 +1,49 @@
+$PI := 3.14159265358979323846264338327950288
+$LN_2 := 0.693147180559945309417232121458176568
+$E := 2.71828182845904523536028747135266250
+
 $abs := fn($Expr: type, x: Expr): Expr {
-	return (x ^ x >> @sizeof(Expr) - 1) - (x >> @sizeof(Expr) - 1)
+	if Expr == uint | Expr == u8 | Expr == u16 | Expr == u32 {
+		return (x ^ x >> @sizeof(Expr) - 1) - (x >> @sizeof(Expr) - 1)
+	} else if Expr == int | Expr == i8 | Expr == i16 | Expr == i32 {
+		return x * (1 - 2 * @intcast(@as(u8, @bitcast(x < 0))))
+	} else if Expr == f32 | Expr == f64 {
+		return x * (1.0 - 2.0 * @floatcast(@itf(@intcast(@as(u8, @bitcast(x < 0))))))
+	}
 }
 $min := fn($Expr: type, a: Expr, b: Expr): Expr {
-	return b + (a - b & a - b >> @sizeof(Expr) - 1)
+	if Expr == uint | Expr == u8 | Expr == u16 | Expr == u32 {
+		return b + (a - b & a - b >> @sizeof(Expr) - 1)
+	} else if Expr == int | Expr == i8 | Expr == i16 | Expr == i32 {
+		return @intcast(@as(u8, @bitcast(a > b))) * b + @intcast(@as(u8, @bitcast(a <= b))) * a
+	} else if Expr == f32 | Expr == f64 {
+		return @floatcast(@itf(@intcast(@as(u8, @bitcast(a > b))))) * b + @floatcast(@itf(@intcast(@as(u8, @bitcast(a <= b))))) * a
+	}
 }
 $max := fn($Expr: type, a: Expr, b: Expr): Expr {
-	return a - (a - b & a - b >> @sizeof(Expr) - 1)
+	if Expr == uint | Expr == u8 | Expr == u16 | Expr == u32 {
+		return a - (a - b & a - b >> @sizeof(Expr) - 1)
+	} else if Expr == int | Expr == i8 | Expr == i16 | Expr == i32 {
+		return @intcast(@as(u8, @bitcast(a > b))) * a + @intcast(@as(u8, @bitcast(a <= b))) * b
+	} else if Expr == f32 | Expr == f64 {
+		return @floatcast(@itf(@intcast(@as(u8, @bitcast(a > b))))) * a + @floatcast(@itf(@intcast(@as(u8, @bitcast(a <= b))))) * b
+	}
 }
 $sign := fn($Expr: type, x: Expr): i8 {
 	return @bitcast(x > 0) - @bitcast(x < 0)
 }
 $log := fn($Expr: type, base: uint, x: Expr): uint {
-	// if x <= 0 {}
-	// if base <= 1 {}
-	result := 0
-	loop if x < base break else {
-		x /= base
-		result += 1
+	if Expr == uint | Expr == u8 | Expr == u16 | Expr == u32 | Expr == int | Expr == i8 | Expr == i16 | Expr == i32 {
+		result := 0
+		loop if x < base break else {
+			x /= base
+			result += 1
+		}
+		return result
 	}
-	return result
+}
+$lerp := fn($T: type, v0: T, v1: T, t: T): T {
+	return (1 - t) * v0 + t * v1
 }
 
 Vec2 := fn($Expr: type): type {
@@ -27,11 +52,10 @@ Vec2 := fn($Expr: type): type {
 
 /* source:
    https://github.com/baker-Xie/FastMath/blob/master/include/fast_math.h */
-$PI := 3.14159265358979323846
 
 SIN_TABLE := [f32].(0.0, 0.02454122852291229, 0.04906767432741801, 0.07356456359966743, 0.0980171403295606, 0.1224106751992162, 0.1467304744553617, 0.1709618887603012, 0.1950903220161282, 0.2191012401568698, 0.2429801799032639, 0.2667127574748984, 0.2902846772544623, 0.3136817403988915, 0.3368898533922201, 0.3598950365349881, 0.3826834323650898, 0.4052413140049899, 0.4275550934302821, 0.4496113296546065, 0.4713967368259976, 0.492898192229784, 0.5141027441932217, 0.5349976198870972, 0.5555702330196022, 0.5758081914178453, 0.5956993044924334, 0.6152315905806268, 0.6343932841636455, 0.6531728429537768, 0.6715589548470183, 0.6895405447370668, 0.7071067811865475, 0.7242470829514669, 0.7409511253549591, 0.7572088465064845, 0.773010453362737, 0.7883464276266062, 0.8032075314806448, 0.8175848131515837, 0.8314696123025452, 0.844853565249707, 0.8577286100002721, 0.8700869911087113, 0.8819212643483549, 0.8932243011955153, 0.9039892931234433, 0.9142097557035307, 0.9238795325112867, 0.9329927988347388, 0.9415440651830208, 0.9495281805930367, 0.9569403357322089, 0.9637760657954398, 0.970031253194544, 0.9757021300385286, 0.9807852804032304, 0.9852776423889412, 0.989176509964781, 0.99247953459871, 0.9951847266721968, 0.9972904566786902, 0.9987954562051724, 0.9996988186962042, 1.0, 0.9996988186962042, 0.9987954562051724, 0.9972904566786902, 0.9951847266721969, 0.99247953459871, 0.989176509964781, 0.9852776423889412, 0.9807852804032304, 0.9757021300385286, 0.970031253194544, 0.9637760657954398, 0.9569403357322089, 0.9495281805930367, 0.9415440651830208, 0.9329927988347388, 0.9238795325112867, 0.9142097557035307, 0.9039892931234434, 0.8932243011955152, 0.881921264348355, 0.8700869911087115, 0.8577286100002721, 0.8448535652497072, 0.8314696123025455, 0.8175848131515837, 0.8032075314806449, 0.7883464276266063, 0.7730104533627371, 0.7572088465064847, 0.740951125354959, 0.7242470829514669, 0.7071067811865476, 0.6895405447370671, 0.6715589548470186, 0.6531728429537766, 0.6343932841636455, 0.6152315905806269, 0.5956993044924335, 0.5758081914178454, 0.5555702330196022, 0.5349976198870972, 0.5141027441932218, 0.4928981922297841, 0.4713967368259979, 0.4496113296546069, 0.427555093430282, 0.4052413140049899, 0.3826834323650899, 0.3598950365349883, 0.3368898533922203, 0.3136817403988914, 0.2902846772544624, 0.2667127574748985, 0.2429801799032641, 0.21910124015687, 0.1950903220161286, 0.1709618887603012, 0.1467304744553618, 0.1224106751992163, 0.09801714032956083, 0.07356456359966773, 0.04906767432741797, 0.02454122852291233, 0.0, -0.02454122852291208, -0.04906767432741772, -0.0735645635996675, -0.09801714032956059, -0.1224106751992161, -0.1467304744553616, -0.170961888760301, -0.1950903220161284, -0.2191012401568698, -0.2429801799032638, -0.2667127574748983, -0.2902846772544621, -0.3136817403988912, -0.3368898533922201, -0.3598950365349881, -0.3826834323650897, -0.4052413140049897, -0.4275550934302818, -0.4496113296546067, -0.4713967368259976, -0.4928981922297839, -0.5141027441932216, -0.5349976198870969, -0.555570233019602, -0.5758081914178453, -0.5956993044924332, -0.6152315905806267, -0.6343932841636453, -0.6531728429537765, -0.6715589548470184, -0.6895405447370668, -0.7071067811865475, -0.7242470829514668, -0.7409511253549589, -0.7572088465064842, -0.7730104533627367, -0.7883464276266059, -0.8032075314806451, -0.8175848131515838, -0.8314696123025452, -0.844853565249707, -0.857728610000272, -0.8700869911087113, -0.8819212643483549, -0.8932243011955152, -0.9039892931234431, -0.9142097557035305, -0.9238795325112865, -0.932992798834739, -0.9415440651830208, -0.9495281805930367, -0.9569403357322088, -0.9637760657954398, -0.970031253194544, -0.9757021300385285, -0.9807852804032303, -0.9852776423889411, -0.9891765099647809, -0.9924795345987101, -0.9951847266721969, -0.9972904566786902, -0.9987954562051724, -0.9996988186962042, -1.0, -0.9996988186962042, -0.9987954562051724, -0.9972904566786902, -0.9951847266721969, -0.9924795345987101, -0.9891765099647809, -0.9852776423889412, -0.9807852804032304, -0.9757021300385286, -0.970031253194544, -0.96377606579544, -0.9569403357322089, -0.9495281805930368, -0.9415440651830209, -0.9329927988347391, -0.9238795325112866, -0.9142097557035306, -0.9039892931234433, -0.8932243011955153, -0.881921264348355, -0.8700869911087115, -0.8577286100002722, -0.8448535652497072, -0.8314696123025455, -0.817584813151584, -0.8032075314806453, -0.7883464276266061, -0.7730104533627369, -0.7572088465064846, -0.7409511253549591, -0.724247082951467, -0.7071067811865477, -0.6895405447370672, -0.6715589548470187, -0.6531728429537771, -0.6343932841636459, -0.6152315905806274, -0.5956993044924332, -0.5758081914178452, -0.5555702330196022, -0.5349976198870973, -0.5141027441932219, -0.4928981922297843, -0.4713967368259979, -0.449611329654607, -0.4275550934302825, -0.4052413140049904, -0.3826834323650904, -0.359895036534988, -0.33688985339222, -0.3136817403988915, -0.2902846772544625, -0.2667127574748986, -0.2429801799032642, -0.2191012401568702, -0.1950903220161287, -0.1709618887603018, -0.1467304744553624, -0.122410675199216, -0.09801714032956051, -0.07356456359966741, -0.04906767432741809, -0.02454122852291245)
 TAN_TABLE := [f32].(0.0, 0.01227246237956628, 0.02454862210892544, 0.03683218099484564, 0.04912684976946725, 0.06143635258159376, 0.07376443152244928, 0.08611485119762791, 0.09849140335716425, 0.110897911595913, 0.1233382361367387, 0.1358162787093877, 0.1483359875383474, 0.1609013624534892, 0.1735164601378558, 0.1861853995275837, 0.198912367379658, 0.2117016240239833, 0.2245575093171293, 0.2374844488160702, 0.2504869601913055, 0.263569659899918, 0.2767372701404143, 0.2899946261126061, 0.3033466836073424, 0.3167985269526038, 0.330355377344334, 0.3440226015924263, 0.3578057213145241, 0.3717104226127435, 0.3857425662711212, 0.3999081985145372, 0.414213562373095, 0.4286651096994995, 0.4432695138908643, 0.4580336833706724, 0.4729647758913199, 0.4880702137228629, 0.5033576997992942, 0.5188352348999757, 0.5345111359507916, 0.5503940555372639, 0.566493002730344, 0.5828173653349761, 0.5993769336819237, 0.616181926094866, 0.6332430161775691, 0.6505713620801533, 0.6681786379192989, 0.6860770675448629, 0.7042794608650442, 0.7227992529642059, 0.7416505462720354, 0.7608481560702512, 0.7804076596539435, 0.8003454494993202, 0.8206787908286602, 0.8414258840072547, 0.8626059322567399, 0.8842392152253498, 0.906347169019147, 0.9289524733703675, 0.9520791467009252, 0.9757526499323765, 0.9999999999999999, 1.024849894150227, 1.05033284623986, 1.076481336415266, 1.103329975733476, 1.130915687498827, 1.159277907333434, 1.188458804282966, 1.218503525587976, 1.249460468133579, 1.281381580036554, 1.31432269635108, 1.34834391348672, 1.383510007652874, 1.419890903494092, 1.457562200087105, 1.496605762665489, 1.537110389861882, 1.579172567960209, 1.622897325693455, 1.668399205583507, 1.715803370795664, 1.765246870094191, 1.816880087892402, 1.870868411789389, 1.927394156630064, 1.986658792343365, 2.04888553303075, 2.11432235754864, 2.183245547884151, 2.255963851929159, 2.33282340310135, 2.414213562373095, 2.500573890994256, 2.592402517738071, 2.690266237279613, 2.794812772490477, 2.906785761665535, 3.027043204317773, 3.156580333940787, 3.296558208938321, 3.448339762033025, 3.613535681307428, 3.7940634000883, 3.992223783770083, 4.210802033502797, 4.453202224414411, 4.723629327882301, 5.027339492125846, 5.370990435003726, 5.763142005118804, 6.21498777108904, 6.741452405414988, 7.362887641324242, 8.107785803676903, 9.017302360424724, 10.15317038760884, 11.61239886143525, 13.55666924235242, 16.27700795993539, 20.35546762498714, 27.15017066569958, 40.73548387208334, 81.48324020654604, 1633123935319537.0, -81.48324020654685, -40.73548387208354, -27.15017066569967, -20.35546762498719, -16.27700795993542, -13.55666924235244, -11.61239886143527, -10.15317038760886, -9.017302360424734, -8.10778580367691, -7.362887641324249, -6.741452405414994, -6.214987771089044, -5.763142005118809, -5.37099043500373, -5.02733949212585, -4.723629327882303, -4.453202224414413, -4.2108020335028, -3.992223783770084, -3.794063400088302, -3.61353568130743, -3.448339762033026, -3.296558208938323, -3.156580333940789, -3.027043204317775, -2.906785761665536, -2.794812772490478, -2.690266237279614, -2.592402517738072, -2.500573890994257, -2.414213562373095, -2.332823403101351, -2.25596385192916, -2.183245547884153, -2.114322357548642, -2.048885533030752, -1.986658792343365, -1.927394156630064, -1.870868411789389, -1.816880087892402, -1.765246870094192, -1.715803370795664, -1.668399205583508, -1.622897325693455, -1.57917256796021, -1.537110389861883, -1.49660576266549, -1.457562200087105, -1.419890903494092, -1.383510007652874, -1.34834391348672, -1.31432269635108, -1.281381580036555, -1.249460468133579, -1.218503525587977, -1.188458804282967, -1.159277907333435, -1.130915687498827, -1.103329975733476, -1.076481336415266, -1.05033284623986, -1.024849894150228, -1.0, -0.9757526499323768, -0.9520791467009256, -0.9289524733703679, -0.9063471690191476, -0.8842392152253504, -0.8626059322567398, -0.8414258840072547, -0.8206787908286604, -0.8003454494993202, -0.7804076596539438, -0.7608481560702515, -0.7416505462720356, -0.7227992529642062, -0.7042794608650446, -0.6860770675448633, -0.6681786379192988, -0.6505713620801532, -0.6332430161775691, -0.6161819260948661, -0.5993769336819238, -0.5828173653349762, -0.5664930027303442, -0.5503940555372643, -0.5345111359507919, -0.5188352348999761, -0.5033576997992947, -0.4880702137228627, -0.4729647758913199, -0.4580336833706724, -0.4432695138908644, -0.4286651096994996, -0.4142135623730952, -0.3999081985145373, -0.3857425662711215, -0.3717104226127437, -0.3578057213145244, -0.3440226015924267, -0.3303553773443338, -0.3167985269526037, -0.3033466836073424, -0.2899946261126062, -0.2767372701404144, -0.2635696598999182, -0.2504869601913056, -0.2374844488160704, -0.2245575093171296, -0.2117016240239837, -0.1989123673796584, -0.1861853995275837, -0.1735164601378557, -0.1609013624534892, -0.1483359875383475, -0.1358162787093878, -0.1233382361367388, -0.1108979115959132, -0.09849140335716448, -0.08611485119762818, -0.0737644315224496, -0.06143635258159368, -0.04912684976946721, -0.03683218099484564, -0.02454862210892548, -0.01227246237956636)
-$TABLE_SIZE := @as(i32, 256)
+$TABLE_SIZE := @as(i32, @sizeof(@TypeOf(SIN_TABLE)) / @sizeof(f32))
 
 sin := fn(theta: f32): f32 {
 	si := @fti(theta * 0.5 * @itf(TABLE_SIZE) / PI)
@@ -55,4 +79,64 @@ tan := fn(theta: f32): f32 {
 	d = d + 1.0 / 3.0 * d * d * d
 	a &= TABLE_SIZE - 1
 	return (TAN_TABLE[@bitcast(a)] + d) / (1.0 - TAN_TABLE[@bitcast(a)] * d)
+}
+
+exp := fn($T: type, x: T): T {
+	if T == f64 | T == f32 {
+		result := @as(T, 1.0)
+		term := @as(T, 1.0)
+		n := @as(int, 1)
+
+		loop if n == 20 break else {
+			term = term * x / @floatcast(@itf(n))
+			result += term
+
+			if abs(T, term) < 0.0000000001 break
+			n += 1
+		}
+
+		return result
+	}
+}
+
+ln := fn($T: type, x: T): T {
+	if T == f64 | T == f32 {
+		if x <= 0.0 return -100000000000000000000000.0
+		if x == 1.0 return 0.0
+		if x == E return 1.0
+
+		scale := @as(T, 0.0)
+		scaled_x := x
+
+		if scaled_x > 2.0 {
+			loop if scaled_x <= 2.0 break else {
+				scaled_x = scaled_x / E
+				scale += 1.0
+			}
+		} else if scaled_x < 1.0 {
+			loop if scaled_x >= 1.0 {
+				scaled_x = scaled_x * E
+				scale -= 1.0
+			}
+		}
+
+		guess := (scaled_x - 1.0) / (scaled_x + 1.0)
+
+		max_iter := 30
+		i := 0
+		loop if i == max_iter break else {
+			exp_g := exp(T, guess)
+			f := exp_g - scaled_x
+			f_prime := exp_g
+
+			delta := f / (f_prime * (1.0 - 0.5 * f * f_prime / (f_prime * f_prime)))
+
+			guess = guess - delta
+
+			if abs(T, delta) < 0.0000000001 break
+			i += 1
+		}
+
+		return guess + scale
+	}
 }
\ No newline at end of file
diff --git a/sysdata/libraries/stn/src/memory.hb b/sysdata/libraries/stn/src/memory.hb
index 609104c..e9bcdcc 100644
--- a/sysdata/libraries/stn/src/memory.hb
+++ b/sysdata/libraries/stn/src/memory.hb
@@ -2,7 +2,11 @@ $PAGE_SIZE := 4096
 $MAX_ALLOC := 0xFF
 $MAX_FREE := 0xFF
 
-$uninit := fn($Expr: type): ?Expr {
+$uninit := fn($Expr: type): Expr {
+	return idk
+}
+
+$nulled := fn($Expr: type): ?Expr {
 	return null
 }
 
@@ -65,12 +69,12 @@ $inl := fn(addr: u16): u32 {
 	return @eca(3, 3, &InlMsg.(0, 2, addr), @sizeof(InlMsg))
 }
 
-CopyMsg := packed struct {a: u8, count: u32, src: ^u8, dest: ^u8}
+CopyMsg := packed struct {a: u8, count: uint, src: ^u8, dest: ^u8}
 $copy := fn($Expr: type, src: ^Expr, dest: ^Expr, count: uint): void {
-	return @eca(3, 2, &CopyMsg.(4, @intcast(count * @sizeof(Expr)), @bitcast(src), @bitcast(dest)), @sizeof(CopyMsg))
+	return @eca(3, 2, &CopyMsg.(4, count * @sizeof(Expr), @bitcast(src), @bitcast(dest)), @sizeof(CopyMsg))
 }
 
-SetMsg := packed struct {a: u8, count: u32, size: u32, src: ^u8, dest: ^u8}
+SetMsg := packed struct {a: u8, count: uint, size: uint, src: ^u8, dest: ^u8}
 $set := fn($Expr: type, src: ^Expr, dest: ^Expr, count: uint): void {
-	return @eca(3, 2, &SetMsg.(5, @intcast(count), @intcast(@sizeof(Expr)), @bitcast(src), @bitcast(dest)), @sizeof(SetMsg))
+	return @eca(3, 2, &SetMsg.(5, count, @sizeof(Expr), @bitcast(src), @bitcast(dest)), @sizeof(SetMsg))
 }
\ No newline at end of file
diff --git a/sysdata/programs/render_example/src/examples/mandelbrot.hb b/sysdata/programs/render_example/src/examples/mandelbrot.hb
index 15c5548..bb05d21 100644
--- a/sysdata/programs/render_example/src/examples/mandelbrot.hb
+++ b/sysdata/programs/render_example/src/examples/mandelbrot.hb
@@ -1,97 +1,24 @@
-ln_f64 := fn(x: f64): f64 {
-	if x <= 0.0 return -100000000000000000000000.0
-	if x == 1.0 return 0.0
-	if x == E return 1.0
-
-	scale := @as(f64, 0.0)
-	scaled_x := x
-
-	if scaled_x > 2.0 {
-		loop if scaled_x <= 2.0 break else {
-			scaled_x = scaled_x / E
-			scale += 1.0
-		}
-	} else if scaled_x < 1.0 {
-		loop if scaled_x >= 1.0 {
-			scaled_x = scaled_x * E
-			scale -= 1.0
-		}
-	}
-
-	guess := (scaled_x - 1.0) / (scaled_x + 1.0)
-
-	max_iter := 30
-	i := 0
-	loop if i == max_iter break else {
-		exp_g := exp_f64(guess)
-		f := exp_g - scaled_x
-		f_prime := exp_g
-
-		delta := f / (f_prime * (1.0 - 0.5 * f * f_prime / (f_prime * f_prime)))
-
-		guess = guess - delta
-
-		if abs_f64(delta) < 0.0000000001 break
-		i += 1
-	}
-
-	return guess + scale
-}
-
-exp_f64 := fn(x: f64): f64 {
-	result := @as(f64, 1.0)
-	term := @as(f64, 1.0)
-	n := @as(int, 1)
-
-	loop if n == 20 break else {
-		term = term * x / @itf(n)
-		result += term
-
-		if abs_f64(term) < 0.0000000001 break
-		n += 1
-	}
-
-	return result
-}
-
-abs_f64 := fn(x: f64): f64 {
-	if x < 0 return -x else return x
-}
-
-lerp_f64 := fn(v0: f64, v1: f64, t: f64): f64 {
-	return v0 + t * (v1 - v0)
-}
-
 render := @use("lib:render")
 sunset := @use("lib:sunset_proto");
-.{log} := @use("stn")
+.{math, log} := @use("stn")
 
 // full mandelbrot
-// $X_MIN := -2.0
-// $X_MAX := 0.47
-// $Y_MIN := -1.12
-// $Y_MAX := 1.12
+$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
+// $X_MIN := -0.94
+// $X_MAX := -0.93
+// $Y_MIN := 0.31
+// $Y_MAX := 0.306
 
 $MAX_ITERATION := 300
 
 $USE_SUNSET := false
 
-$COLOUR_R := 200
-$COLOUR_G := 100
-$COLOUR_B := 255
-
-$LOG_2 := 0.693147180559945309417232121458176568
-$E := 2.71828182845904523536028747135266250
-
-$INTERIOR_COLOUR := render.BLACK
-
-palette := [render.Color].(render.RED, render.YELLOW, render.GREEN, render.CYAN, render.BLUE, render.MAGENTA)
+palette := [render.Color].(render.LIGHT_RED, render.LIGHT_YELLOW, render.LIGHT_GREEN, render.LIGHT_CYAN, render.LIGHT_BLUE, render.LIGHT_MAGENTA)
 $LEN_PALETTE := @sizeof(@TypeOf(palette)) / @sizeof(render.Color)
 
 example := fn(): void {
@@ -108,7 +35,6 @@ example := fn(): void {
 	} else {
 		screen = render.init(false)
 	}
-	screen.clear(INTERIOR_COLOUR)
 
 	x_scale := @as(f64, X_MAX - X_MIN) / @itf(@bitcast(screen.width))
 	y_scale := @as(f64, Y_MAX - Y_MIN) / @itf(@bitcast(screen.height))
@@ -121,12 +47,7 @@ example := fn(): void {
 			y0 := @as(f64, Y_MIN) + @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 {
+			if q * (q + x0 - 0.25) <= 0.25 * y0 * y0 | (x0 + 1.0) * (x0 + 1.0) + y0 * y0 <= 0.0625 {
 				px += 1
 				continue
 			}
@@ -134,31 +55,26 @@ example := fn(): void {
 			x := @as(f64, 0.0)
 			y := @as(f64, 0.0)
 			iteration := 0
-
-			loop if x * x + y * y > @itf(1 << 16) | iteration == MAX_ITERATION break else {
+			// arbitrary, i cant tell the difference between 32 and 1 << 16
+			loop if x * x + y * y > 32.0 | iteration == MAX_ITERATION break else {
 				x_temp := x * x - y * y + x0
 				y = 2 * x * y + y0
 				x = x_temp
 				iteration += 1
 			}
 
-			c := *screen.indexptr(px, py)
-			if c.r != INTERIOR_COLOUR.r | c.b != INTERIOR_COLOUR.b | c.g != INTERIOR_COLOUR.g {
-				px += 1
-				continue
-			}
 			if iteration < MAX_ITERATION {
-				log_zn := ln_f64(x * x + y * y) / 2.0
-				nu := ln_f64(log_zn / LOG_2) / LOG_2
+				log_zn := math.ln(f64, x * x + y * y) / 2
+				nu := math.ln(f64, log_zn / math.LN_2) / math.LN_2
 				smoothed := @itf(@bitcast(iteration + 1)) - nu
 				smoothed_int := @fti(smoothed)
 				normalised := smoothed - @itf(smoothed_int)
 				colour0 := palette[@bitcast(smoothed_int) % LEN_PALETTE]
 				colour1 := palette[@bitcast(smoothed_int + 1) % LEN_PALETTE]
 				colour := render.Color.{
-					r: @intcast(@fti(lerp_f64(@itf(@intcast(colour0.r)), @itf(@intcast(colour1.r)), normalised))),
-					g: @intcast(@fti(lerp_f64(@itf(@intcast(colour0.g)), @itf(@intcast(colour1.g)), normalised))),
-					b: @intcast(@fti(lerp_f64(@itf(@intcast(colour0.b)), @itf(@intcast(colour1.b)), normalised))),
+					r: @intcast(@fti(math.lerp(f64, @itf(@intcast(colour0.r)), @itf(@intcast(colour1.r)), normalised))),
+					g: @intcast(@fti(math.lerp(f64, @itf(@intcast(colour0.g)), @itf(@intcast(colour1.g)), normalised))),
+					b: @intcast(@fti(math.lerp(f64, @itf(@intcast(colour0.b)), @itf(@intcast(colour1.b)), normalised))),
 					a: 0,
 				}
 				screen.put_pixel(.(px, py), colour)
diff --git a/sysdata/system_config.toml b/sysdata/system_config.toml
index a811525..2498783 100644
--- a/sysdata/system_config.toml
+++ b/sysdata/system_config.toml
@@ -16,6 +16,7 @@ comment = "Default AbleOS boot entry."
 protocol = "limine"
 kernel_path = "boot:///kernel_${ARCH}"
 kernel_cmdline = ""
+# resolution = "2560x1440x24"
 # resolution = "1920x1080x24"
 resolution = "1024x768x24"
 # resolution = "640x480x24"

From 5eff0facb17881dce3977b0c43016014c821c056 Mon Sep 17 00:00:00 2001
From: koniifer <koniifer@proton.me>
Date: Mon, 16 Dec 2024 13:22:03 +0000
Subject: [PATCH 6/6] push

---
 Cargo.lock                                    |  6 +-
 sysdata/libraries/render/src/software.hb      |  2 +-
 sysdata/libraries/stn/src/buffer.hb           |  2 +
 sysdata/libraries/stn/src/dt.hb               |  2 +-
 sysdata/libraries/stn/src/lib.hb              | 25 ++++++
 sysdata/libraries/stn/src/math.hb             | 77 ++++++++++---------
 sysdata/libraries/stn/src/sleep.hb            |  4 +-
 .../render_example/src/examples/mandelbrot.hb | 19 +++--
 8 files changed, 88 insertions(+), 49 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index af27ea7..ecdb7f8 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -213,12 +213,12 @@ dependencies = [
 [[package]]
 name = "hbbytecode"
 version = "0.1.0"
-source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#8138d6664fb6983b10192f5a982a8bf5ec327287"
+source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#a1e692eac73fbf44f1fbf816832aaae0ea8f04d7"
 
 [[package]]
 name = "hblang"
 version = "0.1.0"
-source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#8138d6664fb6983b10192f5a982a8bf5ec327287"
+source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#a1e692eac73fbf44f1fbf816832aaae0ea8f04d7"
 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#8138d6664fb6983b10192f5a982a8bf5ec327287"
+source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#a1e692eac73fbf44f1fbf816832aaae0ea8f04d7"
 dependencies = [
  "hbbytecode",
 ]
diff --git a/sysdata/libraries/render/src/software.hb b/sysdata/libraries/render/src/software.hb
index d4959f2..c441068 100644
--- a/sysdata/libraries/render/src/software.hb
+++ b/sysdata/libraries/render/src/software.hb
@@ -141,7 +141,7 @@ Surface := struct {
 	}
 
 	put_line := fn(self: Self, p0: Vec2(uint), p1: Vec2(uint), color: Color): void {
-		if math.abs(uint, p1.y - p0.y) < math.abs(uint, p1.x - p0.x) {
+		if math.abs(int, @bitcast(p1.y - p0.y)) < math.abs(int, @bitcast(p1.x - p0.x)) {
 			if p0.x > p1.x {
 				@inline(put_line_low, self, p1, p0, color)
 			} else {
diff --git a/sysdata/libraries/stn/src/buffer.hb b/sysdata/libraries/stn/src/buffer.hb
index 495f53a..9e0866a 100644
--- a/sysdata/libraries/stn/src/buffer.hb
+++ b/sysdata/libraries/stn/src/buffer.hb
@@ -23,6 +23,7 @@ $write_length := fn(length: uint, msg: ^u8, buffer_id: uint): void {
 BufferMsg := packed struct {operation: u8, msg: ^u8, msg_len: uint}
 
 create := fn(msg: ^u8): uint {
+	// for some reason not inlining here breaks things
 	return @eca(3, 0, BufferMsg.(0, msg, @inline(string.length, msg)), @sizeof(BufferMsg))
 }
 
@@ -35,5 +36,6 @@ $delete_buffer := fn(buffer_id: uint): void {
 }
 
 search := fn(msg: ^u8): uint {
+	// for some reason not inlining here breaks things
 	return @eca(3, 0, BufferMsg.(3, msg, @inline(string.length, msg)), @sizeof(BufferMsg))
 }
\ No newline at end of file
diff --git a/sysdata/libraries/stn/src/dt.hb b/sysdata/libraries/stn/src/dt.hb
index 160d537..543205a 100644
--- a/sysdata/libraries/stn/src/dt.hb
+++ b/sysdata/libraries/stn/src/dt.hb
@@ -1,5 +1,5 @@
 .{string} := @use("../../stn/src/lib.hb")
 
 get := fn($Expr: type, query: ^u8): Expr {
-	return @eca(3, 5, query, @inline(string.length, query))
+	return @eca(3, 5, query, string.length(query))
 }
\ No newline at end of file
diff --git a/sysdata/libraries/stn/src/lib.hb b/sysdata/libraries/stn/src/lib.hb
index 9391917..90b68b7 100644
--- a/sysdata/libraries/stn/src/lib.hb
+++ b/sysdata/libraries/stn/src/lib.hb
@@ -12,6 +12,7 @@ dt := @use("dt.hb")
 process := @use("process.hb")
 sleep := @use("sleep.hb")
 
+// todo: replace with comptime message (for zero cost)
 panic := fn(message: ?^u8): never {
 	log.error("Error: Panic Called, Message:\0")
 	if message == null {
@@ -20,4 +21,28 @@ panic := fn(message: ?^u8): never {
 		log.error(message)
 	}
 	die
+}
+
+$unsigned_int := fn($T: type): bool {
+	return T == uint | T == u8 | T == u16 | T == u32
+}
+
+$signed_int := fn($T: type): bool {
+	return T == int | T == i8 | T == i16 | T == i32
+}
+
+$integer := fn($T: type): bool {
+	return unsigned_int(T) | signed_int(T)
+}
+
+$float := fn($T: type): bool {
+	return T == f32 | T == f64
+}
+
+$primitive := fn($T: type): bool {
+	return integer(T) | float(T) | T == bool
+}
+
+$float_bytes := fn($T: type): type {
+	if T == f64 return uint else if T == f32 return u32
 }
\ No newline at end of file
diff --git a/sysdata/libraries/stn/src/math.hb b/sysdata/libraries/stn/src/math.hb
index d8a9b0e..a234256 100644
--- a/sysdata/libraries/stn/src/math.hb
+++ b/sysdata/libraries/stn/src/math.hb
@@ -1,53 +1,60 @@
+.{unsigned_int, signed_int, integer, float, float_bytes} := @use("stn")
+
 $PI := 3.14159265358979323846264338327950288
 $LN_2 := 0.693147180559945309417232121458176568
 $E := 2.71828182845904523536028747135266250
 
-$abs := fn($Expr: type, x: Expr): Expr {
-	if Expr == uint | Expr == u8 | Expr == u16 | Expr == u32 {
-		return (x ^ x >> @sizeof(Expr) - 1) - (x >> @sizeof(Expr) - 1)
-	} else if Expr == int | Expr == i8 | Expr == i16 | Expr == i32 {
-		return x * (1 - 2 * @intcast(@as(u8, @bitcast(x < 0))))
-	} else if Expr == f32 | Expr == f64 {
-		return x * (1.0 - 2.0 * @floatcast(@itf(@intcast(@as(u8, @bitcast(x < 0))))))
+$abs := fn($T: type, x: T): T {
+	if integer(T) {
+		return (x ^ x >> @sizeof(T) * 8 - 1) - (x >> @sizeof(T) * 8 - 1)
+	} else if float(T) {
+		return @bitcast(@as(float_bytes(T), @bitcast(x)) & (1 << @sizeof(T) * 8) - 1)
 	}
 }
-$min := fn($Expr: type, a: Expr, b: Expr): Expr {
-	if Expr == uint | Expr == u8 | Expr == u16 | Expr == u32 {
-		return b + (a - b & a - b >> @sizeof(Expr) - 1)
-	} else if Expr == int | Expr == i8 | Expr == i16 | Expr == i32 {
-		return @intcast(@as(u8, @bitcast(a > b))) * b + @intcast(@as(u8, @bitcast(a <= b))) * a
-	} else if Expr == f32 | Expr == f64 {
-		return @floatcast(@itf(@intcast(@as(u8, @bitcast(a > b))))) * b + @floatcast(@itf(@intcast(@as(u8, @bitcast(a <= b))))) * a
+// todo: better float min, max
+$min := fn($T: type, a: T, b: T): T {
+	if integer(T) {
+		return b + (a - b & a - b >> @sizeof(T) * 8 - 1)
+	} else if float(T) {
+		return @itf(a > b) * b + @itf(a <= b) * a
 	}
 }
-$max := fn($Expr: type, a: Expr, b: Expr): Expr {
-	if Expr == uint | Expr == u8 | Expr == u16 | Expr == u32 {
-		return a - (a - b & a - b >> @sizeof(Expr) - 1)
-	} else if Expr == int | Expr == i8 | Expr == i16 | Expr == i32 {
-		return @intcast(@as(u8, @bitcast(a > b))) * a + @intcast(@as(u8, @bitcast(a <= b))) * b
-	} else if Expr == f32 | Expr == f64 {
-		return @floatcast(@itf(@intcast(@as(u8, @bitcast(a > b))))) * a + @floatcast(@itf(@intcast(@as(u8, @bitcast(a <= b))))) * b
+$max := fn($T: type, a: T, b: T): T {
+	if integer(T) {
+		return a - (a - b & a - b >> @sizeof(T) - 1)
+	} else if float(T) {
+		return @itf(a > b) * a + @itf(a <= b) * b
 	}
 }
-$sign := fn($Expr: type, x: Expr): i8 {
-	return @bitcast(x > 0) - @bitcast(x < 0)
+$sign := fn($T: type, x: T): i8 {
+	if signed_int(T) {
+		return @intcast(x >> @sizeof(T) * 8 - 1) | x != 0
+	} else if float(T) {
+		sign_bit := @as(float_bytes(T), @bitcast(x)) >> @sizeof(T) * 8 - 1
+		return (1 - 2 * @intcast(sign_bit)) * (x != 0)
+	}
+	return 1
 }
-$log := fn($Expr: type, base: uint, x: Expr): uint {
-	if Expr == uint | Expr == u8 | Expr == u16 | Expr == u32 | Expr == int | Expr == i8 | Expr == i16 | Expr == i32 {
+log := fn($T: type, base: T, x: T): T {
+	if integer(T) {
 		result := 0
 		loop if x < base break else {
 			x /= base
 			result += 1
 		}
 		return result
+	} else if float(T) {
+		return ln(T, x) / ln(T, base)
 	}
 }
 $lerp := fn($T: type, v0: T, v1: T, t: T): T {
-	return (1 - t) * v0 + t * v1
+	if float(T) {
+		return v0 + t * (v1 - v0)
+	}
 }
 
-Vec2 := fn($Expr: type): type {
-	return struct {x: Expr, y: Expr}
+Vec2 := fn($T: type): type {
+	return struct {x: T, y: T}
 }
 
 /* source:
@@ -55,11 +62,11 @@ Vec2 := fn($Expr: type): type {
 
 SIN_TABLE := [f32].(0.0, 0.02454122852291229, 0.04906767432741801, 0.07356456359966743, 0.0980171403295606, 0.1224106751992162, 0.1467304744553617, 0.1709618887603012, 0.1950903220161282, 0.2191012401568698, 0.2429801799032639, 0.2667127574748984, 0.2902846772544623, 0.3136817403988915, 0.3368898533922201, 0.3598950365349881, 0.3826834323650898, 0.4052413140049899, 0.4275550934302821, 0.4496113296546065, 0.4713967368259976, 0.492898192229784, 0.5141027441932217, 0.5349976198870972, 0.5555702330196022, 0.5758081914178453, 0.5956993044924334, 0.6152315905806268, 0.6343932841636455, 0.6531728429537768, 0.6715589548470183, 0.6895405447370668, 0.7071067811865475, 0.7242470829514669, 0.7409511253549591, 0.7572088465064845, 0.773010453362737, 0.7883464276266062, 0.8032075314806448, 0.8175848131515837, 0.8314696123025452, 0.844853565249707, 0.8577286100002721, 0.8700869911087113, 0.8819212643483549, 0.8932243011955153, 0.9039892931234433, 0.9142097557035307, 0.9238795325112867, 0.9329927988347388, 0.9415440651830208, 0.9495281805930367, 0.9569403357322089, 0.9637760657954398, 0.970031253194544, 0.9757021300385286, 0.9807852804032304, 0.9852776423889412, 0.989176509964781, 0.99247953459871, 0.9951847266721968, 0.9972904566786902, 0.9987954562051724, 0.9996988186962042, 1.0, 0.9996988186962042, 0.9987954562051724, 0.9972904566786902, 0.9951847266721969, 0.99247953459871, 0.989176509964781, 0.9852776423889412, 0.9807852804032304, 0.9757021300385286, 0.970031253194544, 0.9637760657954398, 0.9569403357322089, 0.9495281805930367, 0.9415440651830208, 0.9329927988347388, 0.9238795325112867, 0.9142097557035307, 0.9039892931234434, 0.8932243011955152, 0.881921264348355, 0.8700869911087115, 0.8577286100002721, 0.8448535652497072, 0.8314696123025455, 0.8175848131515837, 0.8032075314806449, 0.7883464276266063, 0.7730104533627371, 0.7572088465064847, 0.740951125354959, 0.7242470829514669, 0.7071067811865476, 0.6895405447370671, 0.6715589548470186, 0.6531728429537766, 0.6343932841636455, 0.6152315905806269, 0.5956993044924335, 0.5758081914178454, 0.5555702330196022, 0.5349976198870972, 0.5141027441932218, 0.4928981922297841, 0.4713967368259979, 0.4496113296546069, 0.427555093430282, 0.4052413140049899, 0.3826834323650899, 0.3598950365349883, 0.3368898533922203, 0.3136817403988914, 0.2902846772544624, 0.2667127574748985, 0.2429801799032641, 0.21910124015687, 0.1950903220161286, 0.1709618887603012, 0.1467304744553618, 0.1224106751992163, 0.09801714032956083, 0.07356456359966773, 0.04906767432741797, 0.02454122852291233, 0.0, -0.02454122852291208, -0.04906767432741772, -0.0735645635996675, -0.09801714032956059, -0.1224106751992161, -0.1467304744553616, -0.170961888760301, -0.1950903220161284, -0.2191012401568698, -0.2429801799032638, -0.2667127574748983, -0.2902846772544621, -0.3136817403988912, -0.3368898533922201, -0.3598950365349881, -0.3826834323650897, -0.4052413140049897, -0.4275550934302818, -0.4496113296546067, -0.4713967368259976, -0.4928981922297839, -0.5141027441932216, -0.5349976198870969, -0.555570233019602, -0.5758081914178453, -0.5956993044924332, -0.6152315905806267, -0.6343932841636453, -0.6531728429537765, -0.6715589548470184, -0.6895405447370668, -0.7071067811865475, -0.7242470829514668, -0.7409511253549589, -0.7572088465064842, -0.7730104533627367, -0.7883464276266059, -0.8032075314806451, -0.8175848131515838, -0.8314696123025452, -0.844853565249707, -0.857728610000272, -0.8700869911087113, -0.8819212643483549, -0.8932243011955152, -0.9039892931234431, -0.9142097557035305, -0.9238795325112865, -0.932992798834739, -0.9415440651830208, -0.9495281805930367, -0.9569403357322088, -0.9637760657954398, -0.970031253194544, -0.9757021300385285, -0.9807852804032303, -0.9852776423889411, -0.9891765099647809, -0.9924795345987101, -0.9951847266721969, -0.9972904566786902, -0.9987954562051724, -0.9996988186962042, -1.0, -0.9996988186962042, -0.9987954562051724, -0.9972904566786902, -0.9951847266721969, -0.9924795345987101, -0.9891765099647809, -0.9852776423889412, -0.9807852804032304, -0.9757021300385286, -0.970031253194544, -0.96377606579544, -0.9569403357322089, -0.9495281805930368, -0.9415440651830209, -0.9329927988347391, -0.9238795325112866, -0.9142097557035306, -0.9039892931234433, -0.8932243011955153, -0.881921264348355, -0.8700869911087115, -0.8577286100002722, -0.8448535652497072, -0.8314696123025455, -0.817584813151584, -0.8032075314806453, -0.7883464276266061, -0.7730104533627369, -0.7572088465064846, -0.7409511253549591, -0.724247082951467, -0.7071067811865477, -0.6895405447370672, -0.6715589548470187, -0.6531728429537771, -0.6343932841636459, -0.6152315905806274, -0.5956993044924332, -0.5758081914178452, -0.5555702330196022, -0.5349976198870973, -0.5141027441932219, -0.4928981922297843, -0.4713967368259979, -0.449611329654607, -0.4275550934302825, -0.4052413140049904, -0.3826834323650904, -0.359895036534988, -0.33688985339222, -0.3136817403988915, -0.2902846772544625, -0.2667127574748986, -0.2429801799032642, -0.2191012401568702, -0.1950903220161287, -0.1709618887603018, -0.1467304744553624, -0.122410675199216, -0.09801714032956051, -0.07356456359966741, -0.04906767432741809, -0.02454122852291245)
 TAN_TABLE := [f32].(0.0, 0.01227246237956628, 0.02454862210892544, 0.03683218099484564, 0.04912684976946725, 0.06143635258159376, 0.07376443152244928, 0.08611485119762791, 0.09849140335716425, 0.110897911595913, 0.1233382361367387, 0.1358162787093877, 0.1483359875383474, 0.1609013624534892, 0.1735164601378558, 0.1861853995275837, 0.198912367379658, 0.2117016240239833, 0.2245575093171293, 0.2374844488160702, 0.2504869601913055, 0.263569659899918, 0.2767372701404143, 0.2899946261126061, 0.3033466836073424, 0.3167985269526038, 0.330355377344334, 0.3440226015924263, 0.3578057213145241, 0.3717104226127435, 0.3857425662711212, 0.3999081985145372, 0.414213562373095, 0.4286651096994995, 0.4432695138908643, 0.4580336833706724, 0.4729647758913199, 0.4880702137228629, 0.5033576997992942, 0.5188352348999757, 0.5345111359507916, 0.5503940555372639, 0.566493002730344, 0.5828173653349761, 0.5993769336819237, 0.616181926094866, 0.6332430161775691, 0.6505713620801533, 0.6681786379192989, 0.6860770675448629, 0.7042794608650442, 0.7227992529642059, 0.7416505462720354, 0.7608481560702512, 0.7804076596539435, 0.8003454494993202, 0.8206787908286602, 0.8414258840072547, 0.8626059322567399, 0.8842392152253498, 0.906347169019147, 0.9289524733703675, 0.9520791467009252, 0.9757526499323765, 0.9999999999999999, 1.024849894150227, 1.05033284623986, 1.076481336415266, 1.103329975733476, 1.130915687498827, 1.159277907333434, 1.188458804282966, 1.218503525587976, 1.249460468133579, 1.281381580036554, 1.31432269635108, 1.34834391348672, 1.383510007652874, 1.419890903494092, 1.457562200087105, 1.496605762665489, 1.537110389861882, 1.579172567960209, 1.622897325693455, 1.668399205583507, 1.715803370795664, 1.765246870094191, 1.816880087892402, 1.870868411789389, 1.927394156630064, 1.986658792343365, 2.04888553303075, 2.11432235754864, 2.183245547884151, 2.255963851929159, 2.33282340310135, 2.414213562373095, 2.500573890994256, 2.592402517738071, 2.690266237279613, 2.794812772490477, 2.906785761665535, 3.027043204317773, 3.156580333940787, 3.296558208938321, 3.448339762033025, 3.613535681307428, 3.7940634000883, 3.992223783770083, 4.210802033502797, 4.453202224414411, 4.723629327882301, 5.027339492125846, 5.370990435003726, 5.763142005118804, 6.21498777108904, 6.741452405414988, 7.362887641324242, 8.107785803676903, 9.017302360424724, 10.15317038760884, 11.61239886143525, 13.55666924235242, 16.27700795993539, 20.35546762498714, 27.15017066569958, 40.73548387208334, 81.48324020654604, 1633123935319537.0, -81.48324020654685, -40.73548387208354, -27.15017066569967, -20.35546762498719, -16.27700795993542, -13.55666924235244, -11.61239886143527, -10.15317038760886, -9.017302360424734, -8.10778580367691, -7.362887641324249, -6.741452405414994, -6.214987771089044, -5.763142005118809, -5.37099043500373, -5.02733949212585, -4.723629327882303, -4.453202224414413, -4.2108020335028, -3.992223783770084, -3.794063400088302, -3.61353568130743, -3.448339762033026, -3.296558208938323, -3.156580333940789, -3.027043204317775, -2.906785761665536, -2.794812772490478, -2.690266237279614, -2.592402517738072, -2.500573890994257, -2.414213562373095, -2.332823403101351, -2.25596385192916, -2.183245547884153, -2.114322357548642, -2.048885533030752, -1.986658792343365, -1.927394156630064, -1.870868411789389, -1.816880087892402, -1.765246870094192, -1.715803370795664, -1.668399205583508, -1.622897325693455, -1.57917256796021, -1.537110389861883, -1.49660576266549, -1.457562200087105, -1.419890903494092, -1.383510007652874, -1.34834391348672, -1.31432269635108, -1.281381580036555, -1.249460468133579, -1.218503525587977, -1.188458804282967, -1.159277907333435, -1.130915687498827, -1.103329975733476, -1.076481336415266, -1.05033284623986, -1.024849894150228, -1.0, -0.9757526499323768, -0.9520791467009256, -0.9289524733703679, -0.9063471690191476, -0.8842392152253504, -0.8626059322567398, -0.8414258840072547, -0.8206787908286604, -0.8003454494993202, -0.7804076596539438, -0.7608481560702515, -0.7416505462720356, -0.7227992529642062, -0.7042794608650446, -0.6860770675448633, -0.6681786379192988, -0.6505713620801532, -0.6332430161775691, -0.6161819260948661, -0.5993769336819238, -0.5828173653349762, -0.5664930027303442, -0.5503940555372643, -0.5345111359507919, -0.5188352348999761, -0.5033576997992947, -0.4880702137228627, -0.4729647758913199, -0.4580336833706724, -0.4432695138908644, -0.4286651096994996, -0.4142135623730952, -0.3999081985145373, -0.3857425662711215, -0.3717104226127437, -0.3578057213145244, -0.3440226015924267, -0.3303553773443338, -0.3167985269526037, -0.3033466836073424, -0.2899946261126062, -0.2767372701404144, -0.2635696598999182, -0.2504869601913056, -0.2374844488160704, -0.2245575093171296, -0.2117016240239837, -0.1989123673796584, -0.1861853995275837, -0.1735164601378557, -0.1609013624534892, -0.1483359875383475, -0.1358162787093878, -0.1233382361367388, -0.1108979115959132, -0.09849140335716448, -0.08611485119762818, -0.0737644315224496, -0.06143635258159368, -0.04912684976946721, -0.03683218099484564, -0.02454862210892548, -0.01227246237956636)
-$TABLE_SIZE := @as(i32, @sizeof(@TypeOf(SIN_TABLE)) / @sizeof(f32))
+$TABLE_SIZE := @sizeof(@TypeOf(SIN_TABLE)) / @sizeof(f32)
 
 sin := fn(theta: f32): f32 {
 	si := @fti(theta * 0.5 * @itf(TABLE_SIZE) / PI)
-	d := theta - @floatcast(@itf(si)) * 2.0 * PI / @floatcast(@itf(TABLE_SIZE))
+	d := theta - @itf(si) * 2.0 * PI / TABLE_SIZE
 	ci := si + TABLE_SIZE / 4 & TABLE_SIZE - 1
 	si &= TABLE_SIZE - 1
 	return SIN_TABLE[@bitcast(si)] + (SIN_TABLE[@bitcast(ci)] - 0.5 * SIN_TABLE[@bitcast(si)] * d) * d
@@ -67,7 +74,7 @@ sin := fn(theta: f32): f32 {
 
 cos := fn(theta: f32): f32 {
 	ci := @fti(theta * 0.5 * @itf(TABLE_SIZE) / PI)
-	d := theta - @floatcast(@itf(ci)) * 2.0 * PI / @floatcast(@itf(TABLE_SIZE))
+	d := theta - @itf(ci) * 2.0 * PI / TABLE_SIZE
 	si := ci + TABLE_SIZE / 4 & TABLE_SIZE - 1
 	ci &= TABLE_SIZE - 1
 	return SIN_TABLE[@bitcast(si)] - (SIN_TABLE[@bitcast(ci)] + 0.5 * SIN_TABLE[@bitcast(si)] * d) * d
@@ -75,20 +82,20 @@ cos := fn(theta: f32): f32 {
 
 tan := fn(theta: f32): f32 {
 	a := @fti(theta * @itf(TABLE_SIZE) / PI)
-	d := theta - @floatcast(@itf(a)) * PI / @itf(TABLE_SIZE)
+	d := theta - @itf(a) * PI / TABLE_SIZE
 	d = d + 1.0 / 3.0 * d * d * d
 	a &= TABLE_SIZE - 1
 	return (TAN_TABLE[@bitcast(a)] + d) / (1.0 - TAN_TABLE[@bitcast(a)] * d)
 }
 
 exp := fn($T: type, x: T): T {
-	if T == f64 | T == f32 {
+	if float(T) {
 		result := @as(T, 1.0)
 		term := @as(T, 1.0)
 		n := @as(int, 1)
 
 		loop if n == 20 break else {
-			term = term * x / @floatcast(@itf(n))
+			term = term * x / @itf(n)
 			result += term
 
 			if abs(T, term) < 0.0000000001 break
@@ -100,7 +107,7 @@ exp := fn($T: type, x: T): T {
 }
 
 ln := fn($T: type, x: T): T {
-	if T == f64 | T == f32 {
+	if float(T) {
 		if x <= 0.0 return -100000000000000000000000.0
 		if x == 1.0 return 0.0
 		if x == E return 1.0
diff --git a/sysdata/libraries/stn/src/sleep.hb b/sysdata/libraries/stn/src/sleep.hb
index 5aeaf14..3beec5e 100644
--- a/sysdata/libraries/stn/src/sleep.hb
+++ b/sysdata/libraries/stn/src/sleep.hb
@@ -1,7 +1,7 @@
-subscribe_to_interrupt := fn(interrupt_number: u8): bool {
+$subscribe_to_interrupt := fn(interrupt_number: u8): bool {
 	return false
 }
 // Pauses execution until the interrupt occures
-sleep_until_interrupt := fn(interrupt_number: u8): void {
+$sleep_until_interrupt := fn(interrupt_number: u8): void {
 	@eca(6, interrupt_number)
 }
\ No newline at end of file
diff --git a/sysdata/programs/render_example/src/examples/mandelbrot.hb b/sysdata/programs/render_example/src/examples/mandelbrot.hb
index bb05d21..c73c973 100644
--- a/sysdata/programs/render_example/src/examples/mandelbrot.hb
+++ b/sysdata/programs/render_example/src/examples/mandelbrot.hb
@@ -22,6 +22,11 @@ palette := [render.Color].(render.LIGHT_RED, render.LIGHT_YELLOW, render.LIGHT_G
 $LEN_PALETTE := @sizeof(@TypeOf(palette)) / @sizeof(render.Color)
 
 example := fn(): void {
+	z := math.log(f32, 10.0, 100.0)
+	z2 := math.sign(f32, 10.0)
+	z = math.min(f32, 10.0, 100.0)
+	z = math.max(f32, 10.0, 100.0)
+
 	screen := @as(render.Surface, idk)
 	window := @as(?sunset.Window, null)
 	if USE_SUNSET {
@@ -66,15 +71,15 @@ example := fn(): void {
 			if iteration < MAX_ITERATION {
 				log_zn := math.ln(f64, x * x + y * y) / 2
 				nu := math.ln(f64, log_zn / math.LN_2) / math.LN_2
-				smoothed := @itf(@bitcast(iteration + 1)) - nu
+				smoothed := @as(f64, @itf(@bitcast(iteration + 1))) - nu
 				smoothed_int := @fti(smoothed)
 				normalised := smoothed - @itf(smoothed_int)
 				colour0 := palette[@bitcast(smoothed_int) % LEN_PALETTE]
 				colour1 := palette[@bitcast(smoothed_int + 1) % LEN_PALETTE]
 				colour := render.Color.{
-					r: @intcast(@fti(math.lerp(f64, @itf(@intcast(colour0.r)), @itf(@intcast(colour1.r)), normalised))),
-					g: @intcast(@fti(math.lerp(f64, @itf(@intcast(colour0.g)), @itf(@intcast(colour1.g)), normalised))),
-					b: @intcast(@fti(math.lerp(f64, @itf(@intcast(colour0.b)), @itf(@intcast(colour1.b)), normalised))),
+					r: @intcast(@fti(math.lerp(f64, @itf(colour0.r), @itf(colour1.r), normalised))),
+					g: @intcast(@fti(math.lerp(f64, @itf(colour0.g), @itf(colour1.g), normalised))),
+					b: @intcast(@fti(math.lerp(f64, @itf(colour0.b), @itf(colour1.b), normalised))),
 					a: 0,
 				}
 				screen.put_pixel(.(px, py), colour)
@@ -82,8 +87,8 @@ example := fn(): void {
 			px += 1
 		}
 		py += 1
-	}
-	if USE_SUNSET loop {
-		_ = sunset.client.send_frame(window)
+		if USE_SUNSET {
+			_ = sunset.client.send_frame(window)
+		}
 	}
 }
\ No newline at end of file