diff --git a/Cargo.lock b/Cargo.lock index bfd0b3e1..25cd7bfc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -350,12 +350,12 @@ checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb" [[package]] name = "hbbytecode" version = "0.1.0" -source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#6d7e726066109e8b08f049bbc4684bba2a2eb88a" +source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#c9b85f9004b7a5d4a4cad68bdf4eb2c1e75d811e" [[package]] name = "hblang" version = "0.1.0" -source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#6d7e726066109e8b08f049bbc4684bba2a2eb88a" +source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#c9b85f9004b7a5d4a4cad68bdf4eb2c1e75d811e" dependencies = [ "hashbrown 0.15.0", "hbbytecode", @@ -367,7 +367,7 @@ dependencies = [ [[package]] name = "hbvm" version = "0.1.0" -source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#6d7e726066109e8b08f049bbc4684bba2a2eb88a" +source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#c9b85f9004b7a5d4a4cad68bdf4eb2c1e75d811e" dependencies = [ "hbbytecode", ] diff --git a/kernel/src/holeybytes/ecah.rs b/kernel/src/holeybytes/ecah.rs index 8d676927..0d077d36 100644 --- a/kernel/src/holeybytes/ecah.rs +++ b/kernel/src/holeybytes/ecah.rs @@ -97,7 +97,8 @@ pub fn handler(vm: &mut Vm) { match msg_type { 0 => unsafe { let size = msg_vec[1]; - let addr = u16::from_le_bytes(msg_vec[2..4].try_into().unwrap()); + let addr = + u16::from_le_bytes(msg_vec[2..4].try_into().unwrap_unchecked()); let value = match size { 0 => x86_in::(addr) as u64, 1 => x86_in::(addr) as u64, @@ -109,7 +110,8 @@ pub fn handler(vm: &mut Vm) { }, 1 => unsafe { let size = msg_vec[1]; - let addr = u16::from_le_bytes(msg_vec[2..4].try_into().unwrap()); + let addr = + u16::from_le_bytes(msg_vec[2..4].try_into().unwrap_unchecked()); // info!("Setting address {}", addr); match size { @@ -173,7 +175,7 @@ pub fn handler(vm: &mut Vm) { Ok(msg) => msg, Err(_) => return, }; - if msg.len() > max_length.try_into().unwrap() { + if msg.len() > unsafe { max_length.try_into().unwrap_unchecked() } { info!("{}", max_length); error!("Message is too long to map in."); } else { diff --git a/kernel/src/holeybytes/kernel_services/mem_serve.rs b/kernel/src/holeybytes/kernel_services/mem_serve.rs index 935ca9ba..e99a1aa4 100644 --- a/kernel/src/holeybytes/kernel_services/mem_serve.rs +++ b/kernel/src/holeybytes/kernel_services/mem_serve.rs @@ -32,40 +32,37 @@ pub fn memory_msg_handler( let msg_vec = block_read(mem_addr, length); let msg_type = msg_vec[0]; match msg_type { - 0 => { + 0 => unsafe { let page_count = msg_vec[1]; let mptr_raw: [u8; 8] = msg_vec[2..10].try_into().unwrap(); let mptr: u64 = u64::from_le_bytes(mptr_raw); log::debug!("Allocating {} pages @ {:x}", page_count, mptr); - let ptr = unsafe { - alloc(Layout::from_size_align_unchecked( - page_count as usize * 4096, - 4096, - )) - }; + let ptr = alloc(Layout::from_size_align_unchecked( + page_count as usize * 4096, + 4096, + )); vm.registers[1] = hbvm::value::Value(ptr as u64); log::debug!("Kernel ptr: {:x}", ptr as u64); - } + }, - 1 => { + 1 => unsafe { let page_count = msg_vec[1]; let mptr_raw: [u8; 8] = msg_vec[2..10].try_into().unwrap(); let mptr: u64 = u64::from_le_bytes(mptr_raw); log::debug!("Deallocating {} pages @ {:x}", page_count, mptr); - unsafe { - dealloc( - mptr as *mut u8, - Layout::from_size_align_unchecked(page_count as usize * 4096, 4096), - ) - } - } + + dealloc( + mptr as *mut u8, + Layout::from_size_align_unchecked(page_count as usize * 4096, 4096), + ) + }, 2 => { use MemoryQuotaType::*; - let quota_type = match msg_vec[0] { + let quota_type = match msg_vec[1] { 0 => NoQuota, 1 => SoftQuota, 2 => HardQuota, @@ -82,10 +79,42 @@ pub fn memory_msg_handler( ) } 3 => { - let page_count = msg_vec[0]; + let page_count = msg_vec[1]; log::debug!(" {} pages", page_count); } + // memcpy + 4 => unsafe { + 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; + src.copy_to(dest, count); + }, + // memset + 5 => unsafe { + 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 dest = u64::from_le_bytes(msg_vec[17..25].try_into().unwrap_unchecked()) as *mut u8; + let src = u64::from_le_bytes(msg_vec[25..33].try_into().unwrap_unchecked()) as *mut u8; + let total_size = count * size; + + if total_size > 32 { + core::ptr::copy(src, dest, size); + let pattern = core::slice::from_raw_parts(dest, size); + let mut offset = size; + + while offset < total_size { + let remaining = total_size - offset; + let copy_size = remaining.min(offset); + core::ptr::copy_nonoverlapping(pattern.as_ptr(), dest.add(offset), copy_size); + offset += copy_size; + } + } else { + for i in 0..total_size { + *dest.add(i) = *src.add(i % size); + } + } + }, _ => { log::debug!("Unknown memory service message type: {}", msg_type); } diff --git a/kernel/src/holeybytes/mem.rs b/kernel/src/holeybytes/mem.rs index 79a36149..94d65833 100644 --- a/kernel/src/holeybytes/mem.rs +++ b/kernel/src/holeybytes/mem.rs @@ -37,7 +37,6 @@ impl hbvm::mem::Memory for Memory { target: *mut u8, count: usize, ) -> Result<(), hbvm::mem::LoadError> { - // if addr.get() % 4096 == 0 {} core::ptr::copy_nonoverlapping(addr.get() as *const u8, target, count); Ok(()) } diff --git a/repbuild/src/main.rs b/repbuild/src/main.rs index 4420c29e..9963774e 100644 --- a/repbuild/src/main.rs +++ b/repbuild/src/main.rs @@ -395,12 +395,7 @@ fn run(release: bool, target: Target, do_accel: bool) -> Result<(), Error> { "-parallel", "none", "-monitor", "none", "-machine", accel, - "-cpu", - if accel != "accel=tcg" { - "host" - } else { - "Broadwell-v4" - }, + "-cpu", "max", "-device", "isa-debug-exit,iobase=0xf4,iosize=0x04", ]); } diff --git a/sysdata/libraries/dt_api/src/lib.hb b/sysdata/libraries/dt_api/src/lib.hb index 8f2dffe3..9159c839 100644 --- a/sysdata/libraries/dt_api/src/lib.hb +++ b/sysdata/libraries/dt_api/src/lib.hb @@ -1,6 +1,6 @@ .{string} := @use("../../stn/src/lib.hb") -dt_get := fn(query: ^u8): int { +dt_get := fn($Expr: type, query: ^u8): Expr { length := string.length(query) return @eca(3, 5, query, length) } \ No newline at end of file diff --git a/sysdata/libraries/render/src/image.hb b/sysdata/libraries/render/src/image.hb new file mode 100644 index 00000000..ee43be28 --- /dev/null +++ b/sysdata/libraries/render/src/image.hb @@ -0,0 +1,51 @@ +.{Color} := @use("./lib.hb"); +.{memory, log} := @use("../../stn/src/lib.hb") + +Image := struct { + buf: ^Color, + width: i32, + height: i32, +} + +BitmapFileHeader := packed struct { + img_type: u16, + size: u32, + reserved_1: u16, + reserved_2: u16, + offset: u32, +} + +BitmapInfoHeader := packed struct { + size: u32, + width: i32, + height: i32, + planes: u16, + bits: u16, + compression: u32, + image_size: u32, + x_resolution: i32, + y_resolution: i32, + n_colours: u32, + important_colours: u32, +} + +BitmapColorHeader := packed struct { + red_mask: u32, + green_mask: u32, + blue_mask: u32, + alpha_mask: u32, + color_space_type: u32, + unused: u32, +} + +from_bmp := fn(bmp: ^u8): Image { + file_header := @as(^BitmapFileHeader, @bitcast(bmp)) + if file_header.img_type != 0x4D42 { + log.error("failed to load bmp image: not a bmp image, idiot\0") + return @as(Image, idk) + } + info_header := @as(^BitmapInfoHeader, @bitcast(bmp + @sizeof(BitmapFileHeader))) + bmp += file_header.offset + + return .(@bitcast(bmp), @bitcast(info_header.width), @bitcast(info_header.height)) +} \ No newline at end of file diff --git a/sysdata/libraries/render/src/lib.hb b/sysdata/libraries/render/src/lib.hb index 5c0baed8..556387c6 100644 --- a/sysdata/libraries/render/src/lib.hb +++ b/sysdata/libraries/render/src/lib.hb @@ -1,5 +1,6 @@ svga := @use("svga.hb") software := @use("software.hb") +image := @use("image.hb") // default mode mode := software @@ -8,23 +9,24 @@ init := mode.init doublebuffer := mode.doublebuffer // Colours -Color := mode.Color -white := mode.white -black := mode.black -gray := mode.gray -red := mode.red -green := mode.green -yellow := mode.yellow -blue := mode.blue -magenta := mode.magenta -cyan := mode.cyan -light_gray := mode.light_gray -light_red := mode.light_red -light_green := mode.light_green -light_yellow := mode.light_yellow -light_blue := mode.light_blue -light_magenta := mode.light_magenta -light_cyan := mode.light_cyan +Color := packed struct {b: u8, g: u8, r: u8, a: u8} +Image := image.Image +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 @@ -32,7 +34,11 @@ put_rect := mode.put_rect put_filled_rect := mode.put_filled_rect put_line := mode.put_line clear := mode.clear -put_img := mode.put_img +put_image := mode.put_image +// thanks peony for these three! +put_trirect := mode.put_trirect +put_vline := mode.put_vline +put_hline := mode.put_hline // Display width := mode.width @@ -41,10 +47,4 @@ dimensions := mode.dimensions set_height := mode.set_height set_width := mode.set_width set_dimensions := mode.set_dimensions -sync := mode.sync - -// Trash Image -Image := struct { - start: ^Color, - end: ^Color, -} \ No newline at end of file +sync := mode.sync \ No newline at end of file diff --git a/sysdata/libraries/render/src/software.hb b/sysdata/libraries/render/src/software.hb index a89057b7..01107dff 100644 --- a/sysdata/libraries/render/src/software.hb +++ b/sysdata/libraries/render/src/software.hb @@ -1,62 +1,32 @@ .{math, memory} := @use("../../stn/src/lib.hb"); .{dt_get} := @use("../../dt_api/src/lib.hb"); -.{Image} := @use("lib.hb"); +.{Color, Image} := @use("lib.hb"); .{Vec2} := math -Color := 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) - -// might not work for some resolutions, but needs to be comptime because... -copy_pixels := 0xC000 >> 2 - ctx := @as(Context, idk) -// some of these are redudant holdovers from fb_driver -// will keep them for future work if necessary Context := struct { fb: ^Color, bb: ^Color, buf: ^Color, width: int, height: int, - partitions: int, pixels: int, - bb_pages: int, double_buffer: bool, } init := fn(): void { - width := dt_get("framebuffer/fb0/width\0") - height := dt_get("framebuffer/fb0/height\0") + width := dt_get(int, "framebuffer/fb0/width\0") + height := dt_get(int, "framebuffer/fb0/height\0") pixels := width * height - bytes := pixels << 2 - partitions := pixels / copy_pixels - pages := 1 + bytes >> 12 - back_buffer := create_back_buffer(pages) + back_buffer := memory.alloc(Color, pixels * @bitcast(@sizeof(Color))) ctx = Context.{ - fb: dt_get("framebuffer/fb0/ptr\0"), + fb: dt_get(^Color, "framebuffer/fb0/ptr\0"), bb: back_buffer, buf: back_buffer, width, height, - partitions, pixels, - bb_pages: pages, double_buffer: true, } return @@ -72,60 +42,12 @@ doublebuffer := fn(enable: bool): void { return } -create_back_buffer := fn(pages: int): ^Color { - if pages <= 0xFF { - return @bitcast(@inline(memory.request_page, pages)) - } - ptr := @inline(memory.request_page, 255) - remaining := pages - 0xFF - loop if remaining <= 0 break else { - if remaining < 0xFF { - memory.request_page(remaining) - } else { - memory.request_page(0xFF) - } - remaining -= 0xFF - } - return @bitcast(ptr) -} - clear := fn(color: Color): void { - cursor := ctx.buf - boundary := cursor + 512 - loop if cursor == boundary break else { - *cursor = color - cursor += 1 - } - boundary += 512 * 7 - loop if cursor == boundary break else { - *@as(^[Color; 512], @bitcast(cursor)) = *@as(^[Color; 512], @bitcast(ctx.buf)) - cursor += 512 - } - boundary += copy_pixels - 4096 - loop if cursor == boundary break else { - *@as(^[Color; 4096], @bitcast(cursor)) = *@as(^[Color; 4096], @bitcast(ctx.buf)) - cursor += 4096 - } - boundary += (ctx.partitions - 1) * copy_pixels - loop if cursor == boundary break else { - *@as(^[Color; copy_pixels], @bitcast(cursor)) = *@as(^[Color; copy_pixels], @bitcast(ctx.buf)) - cursor += @sizeof([u8; copy_pixels]) - } - return + return @inline(memory.set, Color, &color, ctx.buf, @bitcast(ctx.pixels)) } sync := fn(): void { - if ctx.double_buffer { - bb := ctx.buf - fb := ctx.fb - boundary := bb + ctx.pixels - loop if bb == boundary break else { - *@as(^[Color; copy_pixels], @bitcast(fb)) = *@as(^[Color; copy_pixels], @bitcast(bb)) - bb += copy_pixels - fb += copy_pixels - } - } - return + return @inline(memory.copy, Color, ctx.buf, ctx.fb, @bitcast(ctx.pixels)) } width := fn(): int { @@ -146,35 +68,25 @@ put_pixel := fn(pos: Vec2(int), color: Color): void { } put_filled_rect := fn(pos: Vec2(int), tr: Vec2(int), color: Color): void { - x := pos.x y := pos.y - end := pos + tr - loop if x == end.x break else { - loop if y == end.y break else { - *(ctx.buf + @inline(screenidx, x, y)) = color - y += 1 - } - x += 1 - y = pos.y + end_y := y + tr.y + loop if y == end_y break else { + @inline(memory.set, Color, &color, ctx.buf + @inline(screenidx, pos.x, y), @bitcast(tr.x)) + y += 1 } return } put_rect := fn(pos: Vec2(int), tr: Vec2(int), color: Color): void { - x := pos.x y := pos.y - end := pos + tr - loop if y == end.y break else { - *(ctx.buf + @inline(screenidx, x, y)) = color; - *(ctx.buf + @inline(screenidx, x + tr.x, y)) = color + end_y := y + tr.y + loop if y == end_y break else { + *(ctx.buf + @inline(screenidx, pos.x, y)) = color; + *(ctx.buf + @inline(screenidx, pos.x + tr.x, y)) = color y += 1 } - y = pos.y - loop if x == end.x break else { - *(ctx.buf + @inline(screenidx, x, y)) = color; - *(ctx.buf + @inline(screenidx, x, y + tr.y)) = color - x += 1 - } + @inline(memory.set, Color, &color, ctx.buf + @inline(screenidx, pos.x, y), @bitcast(tr.x)) + @inline(memory.set, Color, &color, ctx.buf + @inline(screenidx, pos.x, y - tr.y), @bitcast(tr.x)) return } @@ -259,6 +171,67 @@ set_dimensions := fn(new: Vec2(int)): void { return } -put_img := fn(img: Image, pos: Vec2(int)): void { +put_image := fn(image: Image, pos: Vec2(int)): void { + y := 0 + loop if y == image.height break else { + @inline(memory.copy, Color, image.buf + y * image.width, ctx.buf + @inline(screenidx, pos.x, pos.y + image.height - y), @intcast(image.width)) + y += 1 + } + return +} + +// peony-made +put_trirect := fn(pos: Vec2(int), 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 = size.y / size.x + } + + start_y := pos.y + target := pos + size + + loop if pos.x == target.x break else { + put_vline(pos.x, pos.y, target.y, color0) + @inline(put_vline, pos.x, pos.y, start_y, color1) + pos += step + } + + return +} + +// peony-made +put_vline := fn(x: int, y0: int, y1: int, color: Color): void { + if y1 < y0 { + tmp := y0 + y0 = y1 + y1 = tmp + } + y := y0 + + loop if y == y1 break else { + *(ctx.buf + @inline(screenidx, x, y)) = color + y += 1 + } + + return +} + +// peony-made +put_hline := fn(y: int, x0: int, x1: int, color: Color): void { + if x1 < x0 { + tmp := x0 + x0 = x1 + x1 = tmp + } + x := x0 + + loop if x == x1 break else { + *(ctx.buf + @inline(screenidx, x, y)) = color + x += 1 + } + return } \ No newline at end of file diff --git a/sysdata/libraries/render/src/svga.hb b/sysdata/libraries/render/src/svga.hb index 0790198e..033d7626 100644 --- a/sysdata/libraries/render/src/svga.hb +++ b/sysdata/libraries/render/src/svga.hb @@ -1,23 +1,5 @@ -.{Vec2, Image} := @use("lib.hb") -// .{pci, memory, string, log} := @use("../../stn/src/lib.hb"); - -Color := 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) +.{Vec2} := @use("../../stn/src/lib.hb").math; +.{Image, Color} := @use("lib.hb") clear := fn(color: Color): void { return @@ -79,6 +61,18 @@ init := fn(): void { return } -put_img := fn(img: Image, pos: Vec2(int)): void { +put_image := fn(img: Image, pos: Vec2(int)): void { + return +} + +put_trirect := fn(pos: Vec2(int), size: Vec2(int), color0: Color, color1: Color): void { + return +} + +put_vline := fn(x: int, y0: int, y1: int, color: Color): void { + return +} + +put_hline := fn(y: int, x0: int, x1: int, color: Color): void { return } \ No newline at end of file diff --git a/sysdata/libraries/stn/src/memory.hb b/sysdata/libraries/stn/src/memory.hb index 4cbdd6d8..21a0387f 100644 --- a/sysdata/libraries/stn/src/memory.hb +++ b/sysdata/libraries/stn/src/memory.hb @@ -1,3 +1,24 @@ +PAGE_SIZE := 4096 +MAX_ALLOC := 0xFF + +alloc := fn($Expr: type, bytes: int): ^Expr { + pages := (1 + bytes) / PAGE_SIZE + if pages <= MAX_ALLOC { + return @bitcast(@inline(request_page, pages)) + } + ptr := @inline(request_page, 0xFF) + remaining := pages - MAX_ALLOC + loop if remaining <= 0 break else { + if remaining < MAX_ALLOC { + request_page(remaining) + } else { + request_page(MAX_ALLOC) + } + remaining -= MAX_ALLOC + } + return @bitcast(ptr) +} + request_page := fn(page_count: u8): ^u8 { msg := "\{00}\{01}xxxxxxxx\0" msg_page_count := msg + 1; @@ -36,4 +57,14 @@ outl := fn(addr: u16, value: u32): void { inl := fn(addr: u16): u32 { return @eca(3, 3, &InlMsg.(0, 2, addr), @sizeof(InlMsg)) +} + +CopyMsg := packed struct {a: u8, count: uint, src: uint, dest: ^u8} +copy := fn($Expr: type, src: ^Expr, dest: ^Expr, count: uint): void { + return @eca(3, 2, &CopyMsg.(4, count * @sizeof(Expr), @bitcast(src), @bitcast(dest)), @sizeof(CopyMsg)) +} + +SetMsg := packed struct {a: u8, count: uint, size: uint, dest: ^u8, src: ^u8} +set := fn($Expr: type, src: ^Expr, dest: ^Expr, count: uint): void { + return @eca(3, 2, &SetMsg.(5, count, @sizeof(Expr), @bitcast(dest), @bitcast(src)), @sizeof(SetMsg)) } \ No newline at end of file diff --git a/sysdata/programs/render_example/src/examples/image.hb b/sysdata/programs/render_example/src/examples/image.hb new file mode 100644 index 00000000..6546d747 --- /dev/null +++ b/sysdata/programs/render_example/src/examples/image.hb @@ -0,0 +1,31 @@ +.{Vec2} := @use("../../../../libraries/stn/src/lib.hb").math; +render := @use("../../../../libraries/render/src/lib.hb") + +/* expected result: + a cute image bounces around the screen */ + +mini_bmp := @embed("./mini.bmp") + +example := fn(): void { + render.init() + mini := render.image.from_bmp(@bitcast(&mini_bmp)) + vel := Vec2(int).(1, 1) + pos := Vec2(int).(100, 100) + width := render.width() + height := render.height() + loop { + render.put_image(mini, pos) + render.sync() + render.clear(render.black) + + if pos.x == 0 | pos.x == width - mini.width { + vel.x = -vel.x + } + if pos.y == 0 | pos.y == height - mini.height { + vel.y = -vel.y + } + + pos += vel + } + return +} \ No newline at end of file diff --git a/sysdata/programs/render_example/src/examples/mini.bmp b/sysdata/programs/render_example/src/examples/mini.bmp new file mode 100644 index 00000000..7e0b4cee Binary files /dev/null and b/sysdata/programs/render_example/src/examples/mini.bmp differ diff --git a/sysdata/programs/render_example/src/examples/tactical_screen.hb b/sysdata/programs/render_example/src/examples/tactical_screen.hb new file mode 100644 index 00000000..4f227de2 --- /dev/null +++ b/sysdata/programs/render_example/src/examples/tactical_screen.hb @@ -0,0 +1,83 @@ +render := @use("../../../../libraries/render/src/lib.hb"); +.{math, random} := @use("../../../../libraries/stn/src/lib.hb") +Vec2 := math.Vec2 + +/* 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*/ + +example := fn(): void { + render.init() + + width := render.width() + height := render.height() + cell_size := 0 + range := Vec2(int).(0, 0) + if width > height { + cell_size = width / 40 + range = .(39, height / cell_size - 1) + } else { + cell_size = height / 40 + range = .(width / cell_size - 1, 39) + } + width -= 1 + height -= 1 + + scroll := 0 + target := Vec2(int).(random.range(int, 0, range.x), random.range(int, 0, range.y)) + + halfcell := cell_size / 2 + octcell := cell_size / 8 + sevenoctcell := cell_size - octcell + + seeker := Vec2(int).(random.range(int, 0, range.x), random.range(int, 0, range.y)) + + loop { + render.clear(render.black) + + target_pixel_coord := target * .(cell_size, cell_size) + .(scroll, scroll) + render.put_trirect(target_pixel_coord, .(cell_size, cell_size), render.red, render.light_red) + + render.put_hline(target_pixel_coord.y + halfcell, target_pixel_coord.x - octcell, target_pixel_coord.x - sevenoctcell, render.light_red) + render.put_hline(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(target_pixel_coord.x + halfcell, target_pixel_coord.y - octcell, target_pixel_coord.y - sevenoctcell, render.light_red) + render.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(x, 0, height, .(0, 127, 0, 127)) + x += cell_size + } + + y := scroll + loop if y > height break else { + render.put_hline(y, 0, width, .(0, 127, 0, 127)) + y += cell_size + } + + render.put_hline(seeker.y * cell_size + halfcell + scroll, 0, width, render.light_green) + render.put_vline(seeker.x * cell_size + halfcell + scroll, 0, height, render.light_green) + + render.sync() + + if seeker.x < target.x { + seeker.x += 1 + } else if seeker.x > target.x { + seeker.x -= 1 + } else if seeker.y < target.y { + seeker.y += 1 + } else if seeker.y > target.y { + seeker.y -= 1 + } else { + target = .(random.range(int, 0, range.x), random.range(int, 0, range.y)) + } + + scroll += 1 + if scroll > cell_size { + scroll = 0 + target += .(1, 1) + seeker += .(1, 1) + } + } + return +} \ No newline at end of file diff --git a/sysdata/programs/render_example/src/main.hb b/sysdata/programs/render_example/src/main.hb index 35b2706e..1ce2d4e6 100644 --- a/sysdata/programs/render_example/src/main.hb +++ b/sysdata/programs/render_example/src/main.hb @@ -1,4 +1,4 @@ -.{example} := @use("./examples/amogus.hb") +.{example} := @use("./examples/image.hb") main := fn(): void { @inline(example) diff --git a/sysdata/programs/tetris/meta.toml b/sysdata/programs/tetris/meta.toml deleted file mode 100644 index d2a5f974..00000000 --- a/sysdata/programs/tetris/meta.toml +++ /dev/null @@ -1,11 +0,0 @@ -[package] -name = "tetris" -authors = ["peony"] - -[dependants.libraries] - -[dependants.binaries] -hblang.version = "1.0.0" - -[build] -command = "hblang src/main.hb" diff --git a/sysdata/programs/tetris/src/main.hb b/sysdata/programs/tetris/src/main.hb deleted file mode 100644 index e61324b3..00000000 --- a/sysdata/programs/tetris/src/main.hb +++ /dev/null @@ -1,15 +0,0 @@ -.{memory, log, string, buffer} := @use("../../../libraries/stn/src/lib.hb") - -main := fn(): void { - storage := @as(u8, 0) - output_buffer := memory.request_page(1) - input_buffer := buffer.search("XKeyboard\0") - loop { - buffer.recv(input_buffer, &storage, 1) - if storage != 0 { - log.info(string.display_int(storage, output_buffer)) - storage = 0 - } - } - return -} \ No newline at end of file