Litrally almost functional PS/2 driver. #19

Open
peony wants to merge 32 commits from peony/ableos:master into master
39 changed files with 697 additions and 461 deletions
Showing only changes of commit b795aced8e - Show all commits

10
Cargo.lock generated
View file

@ -82,9 +82,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
[[package]] [[package]]
name = "cc" name = "cc"
version = "1.2.0" version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1aeb932158bd710538c73702db6945cb68a8fb08c519e6e12706b94263b36db8" checksum = "fd9de9f2205d5ef3fd67e685b0df337994ddd4495e2a28d185500d0e1edfea47"
dependencies = [ dependencies = [
"shlex", "shlex",
] ]
@ -228,12 +228,12 @@ dependencies = [
[[package]] [[package]]
name = "hbbytecode" name = "hbbytecode"
version = "0.1.0" version = "0.1.0"
source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#f524013c34ff5868eadc0afdf1168239f31c7ee0" source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#7058efe75c7ad245db80986e77a97d426b9be8a4"
[[package]] [[package]]
name = "hblang" name = "hblang"
version = "0.1.0" version = "0.1.0"
source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#f524013c34ff5868eadc0afdf1168239f31c7ee0" source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#7058efe75c7ad245db80986e77a97d426b9be8a4"
dependencies = [ dependencies = [
"hashbrown 0.15.1", "hashbrown 0.15.1",
"hbbytecode", "hbbytecode",
@ -245,7 +245,7 @@ dependencies = [
[[package]] [[package]]
name = "hbvm" name = "hbvm"
version = "0.1.0" version = "0.1.0"
source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#f524013c34ff5868eadc0afdf1168239f31c7ee0" source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#7058efe75c7ad245db80986e77a97d426b9be8a4"
dependencies = [ dependencies = [
"hbbytecode", "hbbytecode",
] ]

View file

@ -11,6 +11,7 @@ static mut LAPIC: LocalApic = unsafe { MaybeUninit::zeroed().assume_init() };
static mut IDT: InterruptDescriptorTable = unsafe { MaybeUninit::zeroed().assume_init() }; static mut IDT: InterruptDescriptorTable = unsafe { MaybeUninit::zeroed().assume_init() };
#[repr(u8)] #[repr(u8)]
#[derive(Debug)]
enum Interrupt { enum Interrupt {
Timer = 32, Timer = 32,
ApicErr = u8::MAX - 1, ApicErr = u8::MAX - 1,
@ -66,11 +67,20 @@ extern "x86-interrupt" fn timer(_isf: InterruptStackFrame) {
} }
extern "x86-interrupt" fn apic_err(_: InterruptStackFrame) { extern "x86-interrupt" fn apic_err(_: InterruptStackFrame) {
interrupt(Interrupt::ApicErr);
panic!("Internal APIC error"); panic!("Internal APIC error");
} }
extern "x86-interrupt" fn spurious(_: InterruptStackFrame) { extern "x86-interrupt" fn spurious(_: InterruptStackFrame) {
interrupt(Interrupt::Spurious);
unsafe { unsafe {
LAPIC.end_of_interrupt(); LAPIC.end_of_interrupt();
} }
} }
fn interrupt(interrupt_type: Interrupt){
log::info!("Interrupt type {:?}", interrupt_type);
panic!()
}

View file

@ -111,7 +111,7 @@ unsafe extern "C" fn oops() -> ! {
unsafe extern "C" fn start() -> ! { unsafe extern "C" fn start() -> ! {
logging::init(); logging::init();
crate::logger::init().expect("failed to set logger"); crate::logger::init().expect("failed to set logger");
log::info!("Initialising AKern {}", crate::VERSION); log::debug!("Initialising AKern {}", crate::VERSION);
static HDHM_REQ: HhdmRequest = HhdmRequest::new(0); static HDHM_REQ: HhdmRequest = HhdmRequest::new(0);
memory::init_pt(VirtAddr::new( memory::init_pt(VirtAddr::new(
@ -190,7 +190,7 @@ unsafe extern "C" fn start() -> ! {
// TODO: Add in rdseed and rdrand as sources for randomness // TODO: Add in rdseed and rdrand as sources for randomness
let _rand = xml::XMLElement::new("Random"); let _rand = xml::XMLElement::new("Random");
log::trace!("Getting boot modules"); log::debug!("Getting boot modules");
let bm = MOD_REQ.get_response().get(); let bm = MOD_REQ.get_response().get();
let mut bootmodules = alloc::vec::Vec::new(); let mut bootmodules = alloc::vec::Vec::new();
@ -228,7 +228,7 @@ unsafe extern "C" fn start() -> ! {
break; break;
} }
} }
log::info!("Boot module count: {:?}", bootmodules.len()); log::debug!("Boot module count: {:?}", bootmodules.len());
assert_eq!(bm.module_count, bootmodules.len() as u64); assert_eq!(bm.module_count, bootmodules.len() as u64);
} }

View file

@ -69,7 +69,7 @@ pub fn check_device(bus: u8, device: u8) -> Option<PciDeviceInfo> {
} }
let (reg2, addr) = unsafe { pci_config_read_2(bus, device, 0, 0x8) }; let (reg2, addr) = unsafe { pci_config_read_2(bus, device, 0, 0x8) };
log::info!("pci device-({}) addr {} is {}", device, addr, reg2); log::debug!("pci device-({}) addr {} is {}", device, addr, reg2);
let class = ((reg2 >> 16) & 0x0000_FFFF) as u16; let class = ((reg2 >> 16) & 0x0000_FFFF) as u16;
let pci_class = PciFullClass::from_u16(class); let pci_class = PciFullClass::from_u16(class);
let header_type = get_header_type(bus, device, 0); let header_type = get_header_type(bus, device, 0);

View file

@ -58,10 +58,10 @@ pub fn handler(vm: &mut Vm) {
true => IpcBuffer::new(true, length), true => IpcBuffer::new(true, length),
}, },
); );
info!("Buffer ID: {}", buff_id);
vm.registers[1] = hbvm::value::Value(buff_id); vm.registers[1] = hbvm::value::Value(buff_id);
} }
2 => { 2 => {
log::error!("Oops, deleting buffers is not implemented.")
// Delete buffer // Delete buffer
} }
3 => { 3 => {
@ -182,7 +182,7 @@ pub fn handler(vm: &mut Vm) {
} else { } else {
unsafe { unsafe {
let ptr = map_ptr as *mut u8; let ptr = map_ptr as *mut u8;
ptr.copy_from(msg.as_ptr(), msg.len()); ptr.copy_from_nonoverlapping(msg.as_ptr(), msg.len());
} }
debug!("Recieve {:?} from Buffer({})", msg, buffer_id); debug!("Recieve {:?} from Buffer({})", msg, buffer_id);

View file

@ -9,7 +9,20 @@ use log::Record;
pub fn log_msg_handler(_vm: &mut Vm, mem_addr: u64, length: usize) -> Result<(), LogError> { pub fn log_msg_handler(_vm: &mut Vm, mem_addr: u64, length: usize) -> Result<(), LogError> {
let msg_vec = block_read(mem_addr, length); let msg_vec = block_read(mem_addr, length);
let log_level = msg_vec[0]; use log::Level::*;
let log_level = match msg_vec[0] {
0 | 48 => Error,
1 | 49 => Warn,
2 | 50 => Info,
3 | 51 => Debug,
4 | 52 => Trace,
_ => {
return Err(LogError::InvalidLogFormat);
}
};
if log_level > log::max_level() {
return Ok(());
}
let strptr = u64::from_le_bytes(msg_vec[1..9].try_into().unwrap()); let strptr = u64::from_le_bytes(msg_vec[1..9].try_into().unwrap());
let strlen = u64::from_le_bytes(msg_vec[9..17].try_into().unwrap()) as usize; let strlen = u64::from_le_bytes(msg_vec[9..17].try_into().unwrap()) as usize;
@ -20,18 +33,6 @@ pub fn log_msg_handler(_vm: &mut Vm, mem_addr: u64, length: usize) -> Result<(),
match core::str::from_utf8(&str) { match core::str::from_utf8(&str) {
Ok(strr) => { Ok(strr) => {
use log::Level::*;
let log_level = match log_level {
0 | 48 => Error,
1 | 49 => Warn,
2 | 50 => Info,
3 | 51 => Debug,
4 | 52 => Trace,
_ => {
return Err(LogError::InvalidLogFormat);
}
};
log::logger().log( log::logger().log(
&Record::builder() &Record::builder()
.args(format_args!("{}", strr)) .args(format_args!("{}", strr))

View file

@ -25,42 +25,16 @@ fn alloc_page(vm: &mut Vm, _mem_addr: u64, _length: usize) -> Result<(), MemoryS
} }
#[inline(always)] #[inline(always)]
unsafe fn memset(mut dest: *mut u8, src: *const u8, count: usize, size: usize) { unsafe fn memset(dest: *mut u8, src: *const u8, count: usize, size: usize) {
const BLOCK_SIZE: usize = 64; let total_size = count * size;
let mut remaining = count * size; src.copy_to_nonoverlapping(dest, size);
if remaining < 16 { let mut copied = size;
src.copy_to_nonoverlapping(dest, remaining);
return;
}
let mut buffer = [0u8; BLOCK_SIZE]; while copied < total_size {
let mut buffer_size = size; let copy_size = copied.min(total_size - copied);
src.copy_to_nonoverlapping(buffer.as_mut_ptr(), size); dest.add(copied).copy_from_nonoverlapping(dest, copy_size);
copied += copy_size;
while core::intrinsics::likely(buffer_size * 2 <= BLOCK_SIZE) {
buffer
.as_mut_ptr()
.copy_to_nonoverlapping(buffer.as_mut_ptr().add(buffer_size), buffer_size);
buffer_size *= 2;
}
let buffer_ptr = buffer.as_ptr() as *const u64;
while (dest as usize) & 7 != 0 && remaining >= 8 {
buffer.as_ptr().copy_to_nonoverlapping(dest, 1);
dest = dest.add(1);
remaining -= 1;
}
while core::intrinsics::likely(remaining >= 8) {
*(dest as *mut u64) = *buffer_ptr;
dest = dest.add(8);
remaining -= 8;
}
if remaining > 0 {
buffer.as_ptr().copy_to_nonoverlapping(dest, remaining);
} }
} }

View file

@ -71,7 +71,18 @@ pub fn kmain(_cmdline: &str, boot_modules: BootModules) -> ! {
let cmd = module.cmd.trim_matches('"'); let cmd = module.cmd.trim_matches('"');
let cmd_len = cmd.len() as u64; let cmd_len = cmd.len() as u64;
log::info!("Spawning {} with arguments \"{}\"", module.path, cmd); log::info!(
"Starting {}",
module
.path
.split('/')
.last()
.unwrap()
.split('.')
.next()
.unwrap()
);
log::debug!("Spawning {} with arguments \"{}\"", module.path, cmd);
// decode AbleOS Executable format // decode AbleOS Executable format
let header = &module.bytes[0..46]; let header = &module.bytes[0..46];
@ -92,7 +103,7 @@ pub fn kmain(_cmdline: &str, boot_modules: BootModules) -> ! {
let code_length = u64::from_le_bytes(header[7..15].try_into().unwrap()); let code_length = u64::from_le_bytes(header[7..15].try_into().unwrap());
let data_length = u64::from_le_bytes(header[15..23].try_into().unwrap()); let data_length = u64::from_le_bytes(header[15..23].try_into().unwrap());
let end = (code_length + data_length) as usize; let end = (code_length + data_length) as usize;
log::info!("{code_length} + {data_length} = {end}"); log::debug!("{code_length} + {data_length} = {end}");
let mut thr = ExecThread::new(&module.bytes[offset..end], Address::new(0)); let mut thr = ExecThread::new(&module.bytes[offset..end], Address::new(0));
if cmd_len > 0 { if cmd_len > 0 {

View file

@ -1,5 +1,6 @@
#![allow(unused)] #![allow(unused)]
use std::{ use std::{
collections::HashMap,
fmt::format, fmt::format,
fs::{read_to_string, File}, fs::{read_to_string, File},
io::{BufWriter, Write}, io::{BufWriter, Write},
@ -13,6 +14,7 @@ pub struct Package {
name: String, name: String,
binaries: Vec<String>, binaries: Vec<String>,
build_cmd: String, build_cmd: String,
args: HashMap<String, String>,
} }
impl Package { impl Package {
@ -46,26 +48,32 @@ impl Package {
let mut binaries = vec![]; let mut binaries = vec![];
for (count, (name, table)) in bin_table.into_iter().enumerate() { for (count, (name, table)) in bin_table.into_iter().enumerate() {
// if count != 0 {
binaries.push(name.clone()); binaries.push(name.clone());
// }
} }
let build_table = data.get("build").unwrap(); let build_table = data.get("build").unwrap();
let mut build_cmd: String = build_table.get("command").unwrap().as_str().unwrap().into(); let mut build_cmd: String = build_table.get("command").unwrap().as_str().unwrap().into();
build_cmd.remove(0); build_cmd.remove(0);
// build_cmd.pop(); let mut args: HashMap<String, String> = match build_table.get("args") {
None => HashMap::new(),
Some(v) => v
.as_table()
.unwrap()
.into_iter()
.map(|(k, v)| (k.clone(), v.to_string()))
.collect::<HashMap<String, String>>(),
};
Self { Self {
name, name,
binaries, binaries,
build_cmd, build_cmd,
args,
} }
} }
pub fn build(&self, out: &mut Vec<u8>) -> std::io::Result<()> { pub fn build(&self, out: &mut Vec<u8>) -> std::io::Result<()> {
if self.binaries.contains(&"hblang".to_string()) { if self.binaries.contains(&"hblang".to_string()) {
let file = self.build_cmd.split_ascii_whitespace().last().unwrap(); let file = self.build_cmd.split_ascii_whitespace().last().unwrap();
let path = format!("sysdata/programs/{}/{}", self.name, file); let path = format!("sysdata/programs/{}/{}", self.name, file);
// compile here // compile here
@ -73,6 +81,7 @@ impl Package {
&path, &path,
Options { Options {
fmt: true, fmt: true,
in_house_regalloc: true,
..Default::default() ..Default::default()
}, },
out, out,
@ -87,6 +96,7 @@ impl Package {
hblang::run_compiler( hblang::run_compiler(
&path, &path,
Options { Options {
in_house_regalloc: true,
..Default::default() ..Default::default()
}, },
out, out,
@ -98,6 +108,7 @@ impl Package {
&path, &path,
Options { Options {
dump_asm: true, dump_asm: true,
in_house_regalloc: true,
..Default::default() ..Default::default()
}, },
out, out,

View file

@ -1,13 +1,9 @@
keycodes := @use("keycodes.hb"); keycodes := @use("keycodes.hb");
.{KeyCode} := keycodes .{KeyCode} := keycodes
KeyEvent := struct { KeyEvent := packed struct {
// 0 if down up: bool,
// 1 if up just_triggered: bool,
up: u8,
// 0 if not just triggered
// 1 if just triggered
just_triggered: u8,
key: KeyCode, key: KeyCode,
} }

View file

@ -6,6 +6,17 @@ events := @use("events.hb");
.{KeyEvent, MouseEvent} := events .{KeyEvent, MouseEvent} := events
recieve_key_event := fn(): ?KeyEvent { recieve_key_event := fn(): ?KeyEvent {
kevent := KeyEvent.(false, false, 0)
buf_id := buffer.search("PS/2 Keyboard\0")
// Read out of the Keyboard buffer here
buffer.recv(KeyEvent, buf_id, &kevent)
if kevent.just_triggered {
return kevent
}
return null return null
} }
@ -15,7 +26,7 @@ recieve_mouse_event := fn(): ?MouseEvent {
buf_id := buffer.search("PS/2 Mouse\0") buf_id := buffer.search("PS/2 Mouse\0")
// Read out of the Mouse buffer here // Read out of the Mouse buffer here
buffer.recv(MouseEvent, buf_id, @bitcast(&mevent)) buffer.recv(MouseEvent, buf_id, &mevent)
if mevent.x_change != 0 | mevent.y_change != 0 | mevent.left | mevent.middle | mevent.right { if mevent.x_change != 0 | mevent.y_change != 0 | mevent.left | mevent.middle | mevent.right {
return mevent return mevent

View file

@ -1,7 +1,4 @@
# Images # Images
- General over image format
- Support formats:
- PNG
- Animation - Animation
# API # API

View file

@ -1,5 +1,5 @@
.{Color, Surface, new_surface, put_surface} := @use("../lib.hb"); .{Color, Surface, new_surface, put_surface} := @use("../lib.hb");
.{log, memory} := @use("../../../stn/src/lib.hb") .{log} := @use("../../../stn/src/lib.hb")
BitmapFileHeader := packed struct { BitmapFileHeader := packed struct {
magic: u16, magic: u16,
@ -41,7 +41,7 @@ from := fn(bmp: ^u8): ?Surface {
return null return null
} }
lhs := Surface.(@bitcast(bmp + file_header.offset), info_header.width, info_header.height) 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) rhs := new_surface(info_header.width, info_header.height)
put_surface(rhs, lhs, .(0, 0), true) put_surface(rhs, lhs, .(0, 0), true)

View file

@ -1,5 +1,5 @@
.{Color, Surface, new_surface} := @use("../lib.hb"); .{Color, Surface, new_surface} := @use("../lib.hb");
.{log, memory} := @use("../../../stn/src/lib.hb") .{log} := @use("../../../stn/src/lib.hb")
/* source: /* source:
https://github.com/phoboslab/qoi/blob/master/qoi.h */ https://github.com/phoboslab/qoi/blob/master/qoi.h */
@ -13,7 +13,7 @@ $QOI_OP_RUN := 0xC0
$QOI_OP_RGB := 0xFE $QOI_OP_RGB := 0xFE
$QOI_OP_RGBA := 0xFF $QOI_OP_RGBA := 0xFF
$QOI_MASK_2 := 0xC0 $QOI_MASK_2 := 0xC0
QOI_COLOR_HASH := fn(c: Color): u8 { $QOI_COLOR_HASH := fn(c: Color): u8 {
return (c.r * 3 + c.g * 5 + c.b * 7 + c.a * 11) % 64 return (c.r * 3 + c.g * 5 + c.b * 7 + c.a * 11) % 64
} }
$QOI_MAGIC := 0x716F6966 $QOI_MAGIC := 0x716F6966
@ -89,7 +89,7 @@ from := fn(qoi: ^u8): ?Surface {
run = b1 & 0x3F run = b1 & 0x3F
} }
index[@inline(QOI_COLOR_HASH, px)] = px index[QOI_COLOR_HASH(px)] = px
}; };
*(surface.buf + px_pos) = px *(surface.buf + px_pos) = px

View file

@ -10,19 +10,21 @@ Surface := struct {
buf: ^Color, buf: ^Color,
width: uint, width: uint,
height: uint, height: uint,
size: uint,
} }
new_surface := fn(width: uint, height: uint): Surface { new_surface := fn(width: uint, height: uint): Surface {
return .( return .(
@inline(memory.alloc, Color, width * height), memory.alloc(Color, width * height),
width, width,
height, height,
width * height,
) )
} }
clone_surface := fn(surface: ^Surface): Surface { clone_surface := fn(surface: ^Surface): Surface {
new := new_surface(surface.width, surface.height) new := new_surface(surface.width, surface.height)
@inline(memory.copy, Color, surface.buf, new.buf, @intcast(surface.width * surface.height)) memory.copy(Color, surface.buf, new.buf, @intcast(surface.size))
return new return new
} }
@ -33,42 +35,38 @@ init := fn(doublebuffer: bool): Surface {
if doublebuffer { if doublebuffer {
return new_surface(width, height) return new_surface(width, height)
} else { } else {
return .(framebuffer, width, height) return .(framebuffer, width, height, width * height)
} }
} }
clear := fn(surface: Surface, color: Color): void { $clear := fn(surface: Surface, color: Color): void {
return @inline(memory.set, Color, &color, surface.buf, surface.width * surface.height) memory.set(Color, &color, surface.buf, surface.width * surface.height)
} }
sync := fn(surface: Surface): void { $sync := fn(surface: Surface): void {
if surface.buf == framebuffer { memory.copy(Color, surface.buf, framebuffer, @bitcast(surface.width * surface.height))
return
}
return @inline(memory.copy, Color, surface.buf, framebuffer, @bitcast(surface.width * surface.height))
} }
index := fn(surface: Surface, x: uint, y: uint): uint { $index := fn(surface: Surface, x: uint, y: uint): uint {
return x + surface.width * y return x + surface.width * y
} }
indexptr := fn(surface: Surface, x: uint, y: uint): ^Color { $indexptr := fn(surface: Surface, x: uint, y: uint): ^Color {
return surface.buf + @inline(index, surface, x, y) return surface.buf + index(surface, x, y)
} }
put_pixel := fn(surface: Surface, pos: Vec2(uint), color: Color): void { $put_pixel := fn(surface: Surface, pos: Vec2(uint), color: Color): void {
*@inline(indexptr, surface, pos.x, pos.y) = color return *indexptr(surface, pos.x, pos.y) = color
return
} }
put_filled_rect := fn(surface: Surface, pos: Vec2(uint), tr: Vec2(uint), color: Color): void { put_filled_rect := fn(surface: Surface, pos: Vec2(uint), tr: Vec2(uint), color: Color): void {
top_start_idx := @inline(indexptr, surface, pos.x, pos.y) top_start_idx := indexptr(surface, pos.x, pos.y)
bottom_start_idx := @inline(indexptr, surface, pos.x, pos.y + tr.y - 1) bottom_start_idx := indexptr(surface, pos.x, pos.y + tr.y - 1)
rows_to_fill := tr.y rows_to_fill := tr.y
loop if rows_to_fill <= 1 break else { loop if rows_to_fill <= 1 break else {
@inline(memory.set, Color, &color, top_start_idx, tr.x) memory.set(Color, &color, top_start_idx, tr.x)
@inline(memory.set, Color, &color, bottom_start_idx, tr.x) memory.set(Color, &color, bottom_start_idx, tr.x)
top_start_idx += surface.width top_start_idx += surface.width
bottom_start_idx -= surface.width bottom_start_idx -= surface.width
@ -76,16 +74,16 @@ put_filled_rect := fn(surface: Surface, pos: Vec2(uint), tr: Vec2(uint), color:
} }
if rows_to_fill == 1 { if rows_to_fill == 1 {
@inline(memory.set, Color, &color, top_start_idx, tr.x) memory.set(Color, &color, top_start_idx, tr.x)
} }
return return
} }
put_rect := fn(surface: Surface, pos: Vec2(uint), tr: Vec2(uint), color: Color): void { put_rect := fn(surface: Surface, pos: Vec2(uint), tr: Vec2(uint), color: Color): void {
start_idx := @inline(indexptr, surface, pos.x, pos.y) start_idx := indexptr(surface, pos.x, pos.y)
end_idx := @inline(indexptr, surface, pos.x, pos.y + tr.y) end_idx := indexptr(surface, pos.x, pos.y + tr.y)
right_start_idx := @inline(indexptr, surface, pos.x + tr.x, pos.y) right_start_idx := indexptr(surface, pos.x + tr.x, pos.y)
loop if start_idx > end_idx break else { loop if start_idx > end_idx break else {
*start_idx = color; *start_idx = color;
@ -94,8 +92,8 @@ put_rect := fn(surface: Surface, pos: Vec2(uint), tr: Vec2(uint), color: Color):
right_start_idx += surface.width right_start_idx += surface.width
} }
@inline(memory.set, Color, &color, @inline(indexptr, surface, pos.x, pos.y), @bitcast(tr.x + 1)) memory.set(Color, &color, indexptr(surface, pos.x, pos.y), @bitcast(tr.x + 1))
@inline(memory.set, Color, &color, @inline(indexptr, surface, pos.x, pos.y + tr.y), @bitcast(tr.x + 1)) memory.set(Color, &color, indexptr(surface, pos.x, pos.y + tr.y), @bitcast(tr.x + 1))
return return
} }
@ -112,7 +110,7 @@ put_line_low := fn(surface: Surface, p0: Vec2(uint), p1: Vec2(uint), color: Colo
y := p0.y y := p0.y
x := p0.x x := p0.x
loop if x == p1.x break else { loop if x == p1.x break else {
*@inline(indexptr, surface, x, y) = color *indexptr(surface, x, y) = color
if D > 0 { if D > 0 {
y += yi y += yi
D += 2 * (dy - dx) D += 2 * (dy - dx)
@ -136,7 +134,7 @@ put_line_high := fn(surface: Surface, p0: Vec2(uint), p1: Vec2(uint), color: Col
x := p0.x x := p0.x
y := p0.y y := p0.y
loop if y == p1.y break else { loop if y == p1.y break else {
*@inline(indexptr, surface, x, y) = color *indexptr(surface, x, y) = color
if D > 0 { if D > 0 {
x += xi x += xi
D += 2 * (dx - dy) D += 2 * (dx - dy)
@ -169,8 +167,8 @@ put_surface := fn(surface: Surface, top: Surface, pos: Vec2(uint), flip_v: bool)
src_top_cursor := top.buf src_top_cursor := top.buf
src_bottom_cursor := top.buf + top.width * (top.height - 1) src_bottom_cursor := top.buf + top.width * (top.height - 1)
dst_top_idx := @inline(indexptr, surface, pos.x, pos.y) dst_top_idx := indexptr(surface, pos.x, pos.y)
dst_bottom_idx := @inline(indexptr, surface, pos.x, pos.y + top.height - 1) dst_bottom_idx := indexptr(surface, pos.x, pos.y + top.height - 1)
dst_increment := surface.width dst_increment := surface.width
@ -184,8 +182,8 @@ put_surface := fn(surface: Surface, top: Surface, pos: Vec2(uint), flip_v: bool)
rows_to_copy := top.height rows_to_copy := top.height
loop if rows_to_copy <= 1 break else { loop if rows_to_copy <= 1 break else {
@inline(memory.copy, Color, src_top_cursor, dst_top_idx, top.width) memory.copy(Color, src_top_cursor, dst_top_idx, top.width)
@inline(memory.copy, Color, src_bottom_cursor, dst_bottom_idx, top.width) memory.copy(Color, src_bottom_cursor, dst_bottom_idx, top.width)
dst_top_idx += dst_increment dst_top_idx += dst_increment
dst_bottom_idx -= dst_increment dst_bottom_idx -= dst_increment
@ -195,7 +193,7 @@ put_surface := fn(surface: Surface, top: Surface, pos: Vec2(uint), flip_v: bool)
} }
if rows_to_copy == 1 { if rows_to_copy == 1 {
@inline(memory.copy, Color, src_top_cursor, dst_top_idx, top.width) memory.copy(Color, src_top_cursor, dst_top_idx, top.width)
} }
return return
@ -233,7 +231,7 @@ put_vline := fn(surface: Surface, x: uint, y0: uint, y1: uint, color: Color): vo
y := y0 y := y0
loop if y == y1 break else { loop if y == y1 break else {
*@inline(indexptr, surface, x, y) = color *indexptr(surface, x, y) = color
y += 1 y += 1
} }
@ -247,7 +245,8 @@ put_hline := fn(surface: Surface, y: uint, x0: uint, x1: uint, color: Color): vo
x0 = x1 x0 = x1
x1 = tmp x1 = tmp
} }
@inline(memory.set, Color, &color, @inline(indexptr, surface, x0, y), @bitcast(x1 - x0 - 1)) // x0 = math.min(x0, x1)
memory.set(Color, &color, indexptr(surface, x0, y), @bitcast(x1 - x0 - 1))
return return
} }
@ -255,29 +254,29 @@ put_hline := fn(surface: Surface, y: uint, x0: uint, x1: uint, color: Color): vo
put_circle := fn(surface: Surface, pos: Vec2(uint), radius: uint, color: Color): void { put_circle := fn(surface: Surface, pos: Vec2(uint), radius: uint, color: Color): void {
x := 0 x := 0
y := radius y := radius
error := @as(int, 3) - @as(int, @intcast(2 * radius)); error := @as(int, 3) - @intcast(2 * radius);
*@inline(indexptr, surface, pos.x + radius, pos.y) = color; *indexptr(surface, pos.x + radius, pos.y) = color;
*@inline(indexptr, surface, pos.x - radius, pos.y) = color; *indexptr(surface, pos.x - radius, pos.y) = color;
*@inline(indexptr, surface, pos.x, pos.y + radius) = color; *indexptr(surface, pos.x, pos.y + radius) = color;
*@inline(indexptr, surface, pos.x, pos.y - radius) = color *indexptr(surface, pos.x, pos.y - radius) = color
loop if y < x break else { loop if y < x break else {
x += 1 x += 1
if error > 0 { if error > 0 {
y -= 1 y -= 1
error += 4 * (@as(int, @intcast(x)) - @as(int, @intcast(y))) + 10 error += 4 * (@intcast(x) - @intcast(y)) + 10
} else { } else {
error += 4 * @intcast(x) + 6 error += 4 * @intcast(x) + 6
}; };
*@inline(indexptr, surface, pos.x + x, pos.y + y) = color; *indexptr(surface, pos.x + x, pos.y + y) = color;
*@inline(indexptr, surface, pos.x + y, pos.y + x) = color; *indexptr(surface, pos.x + y, pos.y + x) = color;
*@inline(indexptr, surface, pos.x - x, pos.y + y) = color; *indexptr(surface, pos.x - x, pos.y + y) = color;
*@inline(indexptr, surface, pos.x - y, pos.y + x) = color; *indexptr(surface, pos.x - y, pos.y + x) = color;
*@inline(indexptr, surface, pos.x + x, pos.y - y) = color; *indexptr(surface, pos.x + x, pos.y - y) = color;
*@inline(indexptr, surface, pos.x + y, pos.y - x) = color; *indexptr(surface, pos.x + y, pos.y - x) = color;
*@inline(indexptr, surface, pos.x - x, pos.y - y) = color; *indexptr(surface, pos.x - x, pos.y - y) = color;
*@inline(indexptr, surface, pos.x - y, pos.y - x) = color *indexptr(surface, pos.x - y, pos.y - x) = color
} }
return return
@ -286,24 +285,24 @@ put_circle := fn(surface: Surface, pos: Vec2(uint), radius: uint, color: Color):
put_filled_circle := fn(surface: Surface, pos: Vec2(uint), radius: uint, color: Color): void { put_filled_circle := fn(surface: Surface, pos: Vec2(uint), radius: uint, color: Color): void {
x := 0 x := 0
y := radius y := radius
error := @as(int, 3) - @as(int, @intcast(2 * radius)) error := @as(int, 3) - @intcast(2 * radius)
@inline(put_hline, surface, pos.y - x, pos.x - radius, pos.x + radius, color); put_hline(surface, pos.y - x, pos.x - radius, pos.x + radius, color);
*@inline(indexptr, surface, pos.x, pos.y + radius) = color; *indexptr(surface, pos.x, pos.y + radius) = color;
*@inline(indexptr, surface, pos.x, pos.y - radius) = color *indexptr(surface, pos.x, pos.y - radius) = color
loop if y < x break else { loop if y < x break else {
x += 1 x += 1
if error > 0 { if error > 0 {
@inline(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)
@inline(put_hline, surface, pos.y - y, pos.x - x, pos.x + x, color) put_hline(surface, pos.y - y, pos.x - x, pos.x + x, color)
y -= 1 y -= 1
error += 4 * (@as(int, @intcast(x)) - @as(int, @intcast(y))) + 10 error += 4 * (@intcast(x) - @intcast(y)) + 10
} else { } else {
error += 4 * @intcast(x) + 6 error += 4 * @intcast(x) + 6
} }
@inline(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)
@inline(put_hline, surface, pos.y - x, pos.x - y, pos.x + y, color) put_hline(surface, pos.y - x, pos.x - y, pos.x + y, color)
} }
return return
@ -312,24 +311,24 @@ put_filled_circle := fn(surface: Surface, pos: Vec2(uint), radius: uint, color:
put_textured_circle := fn(surface: Surface, source: Surface, source_pos: Vec2(uint), pos: Vec2(uint), radius: uint): void { put_textured_circle := fn(surface: Surface, source: Surface, source_pos: Vec2(uint), pos: Vec2(uint), radius: uint): void {
x := 0 x := 0
y := radius y := radius
error := @as(int, 3) - @as(int, @intcast(2 * radius)) error := @as(int, 3) - @intcast(2 * radius)
@inline(memory.copy, Color, @inline(indexptr, source, source_pos.x - y, source_pos.y), @inline(indexptr, surface, pos.x - y, pos.y), 2 * y); memory.copy(Color, indexptr(source, source_pos.x - y, source_pos.y), indexptr(surface, pos.x - y, pos.y), 2 * y);
*@inline(indexptr, surface, pos.x, pos.y + y) = *@inline(indexptr, source, source_pos.x, source_pos.y + y); *indexptr(surface, pos.x, pos.y + y) = *indexptr(source, source_pos.x, source_pos.y + y);
*@inline(indexptr, surface, pos.x, pos.y - y) = *@inline(indexptr, source, source_pos.x, source_pos.y - y) *indexptr(surface, pos.x, pos.y - y) = *indexptr(source, source_pos.x, source_pos.y - y)
loop if y < x break else { loop if y < x break else {
x += 1 x += 1
if error > 0 { if error > 0 {
@inline(memory.copy, Color, @inline(indexptr, source, source_pos.x - x, source_pos.y + y), @inline(indexptr, surface, pos.x - x, pos.y + y), 2 * x) memory.copy(Color, indexptr(source, source_pos.x - x, source_pos.y + y), indexptr(surface, pos.x - x, pos.y + y), 2 * x)
@inline(memory.copy, Color, @inline(indexptr, source, source_pos.x - x, source_pos.y - y), @inline(indexptr, surface, pos.x - x, pos.y - y), 2 * x) memory.copy(Color, indexptr(source, source_pos.x - x, source_pos.y - y), indexptr(surface, pos.x - x, pos.y - y), 2 * x)
y -= 1 y -= 1
error += 4 * (@as(int, @intcast(x)) - @as(int, @intcast(y))) + 10 error += 4 * (@intcast(x) - @intcast(y)) + 10
} else { } else {
error += 4 * @intcast(x) + 6 error += 4 * @intcast(x) + 6
} }
@inline(memory.copy, Color, @inline(indexptr, source, source_pos.x - y, source_pos.y + x), @inline(indexptr, surface, pos.x - y, pos.y + x), 2 * y) memory.copy(Color, indexptr(source, source_pos.x - y, source_pos.y + x), indexptr(surface, pos.x - y, pos.y + x), 2 * y)
@inline(memory.copy, Color, @inline(indexptr, source, source_pos.x - y, source_pos.y - x), @inline(indexptr, surface, pos.x - y, pos.y - x), 2 * y) memory.copy(Color, indexptr(source, source_pos.x - y, source_pos.y - x), indexptr(surface, pos.x - y, pos.y - x), 2 * y)
} }
return return
@ -364,7 +363,7 @@ put_text := fn(surface: Surface, font: Font, pos: Vec2(uint), color: Color, str:
str += 1 str += 1
continue continue
} }
glyph_data = @inline(get_glyph, font, *str) glyph_data = get_glyph(font, *str)
} else { } else {
if *str < UNC_TABLE_SIZE { if *str < UNC_TABLE_SIZE {
glyph_index := *(font.unicode + *str) glyph_index := *(font.unicode + *str)
@ -436,7 +435,7 @@ put_text := fn(surface: Surface, font: Font, pos: Vec2(uint), color: Color, str:
cursor.y += next_line_y cursor.y += next_line_y
} }
dest := @inline(indexptr, surface, cursor.x, cursor.y) dest := indexptr(surface, cursor.x, cursor.y)
rows := font.height rows := font.height
loop if rows == 0 break else { loop if rows == 0 break else {

View file

@ -74,16 +74,16 @@ font_from_psf2 := fn(psf: ^u8, unicode: bool): ?Font {
return font return font
} }
get_glyph := fn(font: Font, index: u8): ^u8 { $get_glyph := fn(font: Font, index: u8): ^u8 {
return font.data + @as(uint, index) * font.bytes_per_glyph return font.data + @as(uint, index) * font.bytes_per_glyph
} }
UNC_TABLE_SIZE := 1 << 16 $UNC_TABLE_SIZE := 1 << 16
init_unicode := fn(font: ^Font): void { init_unicode := fn(font: ^Font): void {
font.unicode = memory.alloc(u16, UNC_TABLE_SIZE) font.unicode = memory.alloc(u16, UNC_TABLE_SIZE)
@inline(memory.set, u16, &0xFFFF, font.unicode, UNC_TABLE_SIZE) memory.set(u16, &0xFFFF, font.unicode, UNC_TABLE_SIZE)
table := font.data + font.num_glyphs * font.bytes_per_glyph table := font.data + font.num_glyphs * font.bytes_per_glyph
curr_glyph := @as(u16, 0) curr_glyph := @as(u16, 0)
@ -121,8 +121,6 @@ init_unicode := fn(font: ^Font): void {
next_byte := *table next_byte := *table
if (next_byte & 0xC0) != 0x80 { if (next_byte & 0xC0) != 0x80 {
valid = false valid = false
}
if valid == false {
break break
} }
unicode = unicode << 6 | next_byte & 0x3F unicode = unicode << 6 | next_byte & 0x3F

View file

@ -1,18 +1,18 @@
string := @use("string.hb") string := @use("string.hb")
recv := fn($Expr: type, buffer_id: uint, memory_map_location: ^u8): void { $recv := fn($Expr: type, buffer_id: uint, memory_map_location: ^Expr): void {
return @eca(4, buffer_id, memory_map_location, @sizeof(Expr)) return @eca(4, buffer_id, memory_map_location, @sizeof(Expr))
} }
write := fn($Expr: type, msg: ^Expr, buffer_id: uint): void { $write := fn($Expr: type, buffer_id: uint, msg: ^Expr): void {
return @eca(3, buffer_id, msg, @sizeof(Expr)) return @eca(3, buffer_id, msg, @sizeof(Expr))
} }
recv_length := fn(buffer_id: uint, memory_map_location: ^u8, length: uint): void { $recv_length := fn(length: uint, memory_map_location: ^u8, buffer_id: uint): void {
return @eca(4, buffer_id, memory_map_location, length) return @eca(4, buffer_id, memory_map_location, length)
} }
write_length := fn(msg: ^u8, buffer_id: uint, length: uint): void { $write_length := fn(length: uint, msg: ^u8, buffer_id: uint): void {
return @eca(3, buffer_id, msg, length) return @eca(3, buffer_id, msg, length)
} }
@ -22,6 +22,14 @@ create := fn(msg: ^u8): uint {
return @eca(3, 0, BufferMsg.(0, msg, @inline(string.length, msg)), @sizeof(BufferMsg)) return @eca(3, 0, BufferMsg.(0, msg, @inline(string.length, msg)), @sizeof(BufferMsg))
} }
$create_nameless := fn(): uint {
return @eca(1, 0)
}
$delete_buffer := fn(buffer_id: uint): void {
return @eca(2, buffer_id)
}
search := fn(msg: ^u8): uint { search := fn(msg: ^u8): uint {
return @eca(3, 0, BufferMsg.(3, msg, @inline(string.length, msg)), @sizeof(BufferMsg)) return @eca(3, 0, BufferMsg.(3, msg, @inline(string.length, msg)), @sizeof(BufferMsg))
} }

View file

@ -1,29 +1,14 @@
abs := fn($Expr: type, x: Expr): Expr { $abs := fn($Expr: type, x: Expr): Expr {
mask := x >> @bitcast(@sizeof(Expr) - 1) return (x ^ x >> @sizeof(Expr) - 1) - (x >> @sizeof(Expr) - 1)
return (x ^ mask) - mask
} }
min := fn($Expr: type, a: Expr, b: Expr): Expr { $min := fn($Expr: type, a: Expr, b: Expr): Expr {
c := a - b return b + (a - b & a - b >> @sizeof(Expr) - 1)
return b + (c & c >> @bitcast(@sizeof(Expr) - 1))
} }
max := fn($Expr: type, a: Expr, b: Expr): Expr { $max := fn($Expr: type, a: Expr, b: Expr): Expr {
c := a - b return a - (a - b & a - b >> @sizeof(Expr) - 1)
return a - (c & c >> @bitcast(@sizeof(Expr) - 1))
} }
signum := fn($Expr: type, x: Expr): int { $sign := fn($Expr: type, x: Expr): i8 {
if x > @as(Expr, @intcast(0)) { return @bitcast(x > 0) - @bitcast(x < 0)
return 1
} else if x < @as(Expr, @intcast(0)) {
return -1
} else {
return 0
}
}
signincl := fn($Expr: type, x: Expr): int {
if x > @as(Expr, @intcast(0)) {
return 1
}
return -1
} }
Vec2 := fn($Expr: type): type { Vec2 := fn($Expr: type): type {

View file

@ -1,32 +1,26 @@
PAGE_SIZE := 4096 $PAGE_SIZE := 4096
MAX_ALLOC := 0xFF $MAX_ALLOC := 0xFF
MAX_FREE := 0xFF $MAX_FREE := 0xFF
is_uninit := fn($Expr: type, ptr: ^Expr): bool { $uninit := fn($Expr: type): ?Expr {
i := 0 return null
loop if *(@as(^u8, @bitcast(ptr)) + i) != 0 return false else if i + 1 == @sizeof(Expr) return true else i += 1
}
uninit := fn($Expr: type): Expr {
empty := @as(Expr, idk)
@inline(set, u8, &0, @bitcast(&empty), @sizeof(Expr))
return empty
} }
dangling := fn($Expr: type): ^Expr { dangling := fn($Expr: type): ^Expr {
return @bitcast(@alignof(Expr)) return @bitcast(@alignof(Expr))
} }
calc_pages := fn($Expr: type, num: uint): uint { $calc_pages := fn($Expr: type, num: uint): uint {
return 1 + @sizeof(Expr) * num / PAGE_SIZE return 1 + @sizeof(Expr) * num / PAGE_SIZE
} }
// ! will be replaced, don't get attached
alloc := fn($Expr: type, num: uint): ^Expr { alloc := fn($Expr: type, num: uint): ^Expr {
pages := @inline(calc_pages, Expr, num) pages := calc_pages(Expr, num)
if pages <= MAX_ALLOC { if pages <= MAX_ALLOC {
return @bitcast(request_page(@intcast(pages))) return @bitcast(request_page(@intcast(pages)))
} }
ptr := request_page(0xFF) ptr := request_page(MAX_ALLOC)
remaining := pages - MAX_ALLOC remaining := pages - MAX_ALLOC
loop if remaining < MAX_ALLOC break else { loop if remaining < MAX_ALLOC break else {
_ = request_page(@intcast(MAX_ALLOC)) _ = request_page(@intcast(MAX_ALLOC))
@ -37,46 +31,46 @@ alloc := fn($Expr: type, num: uint): ^Expr {
} }
// ! stub // ! stub
free := fn($Expr: type, ptr: ^Expr, num: uint, nullify: bool): void { $free := fn($Expr: type, ptr: ^Expr, num: uint, nullify: bool): void {
return return
} }
RqPageMsg := packed struct {a: u8, count: u8} RqPageMsg := packed struct {a: u8, count: u8}
request_page := fn(count: u8): ^u8 { $request_page := fn(count: u8): ^u8 {
return @eca(3, 2, &RqPageMsg.(0, count), @sizeof(RqPageMsg)) return @eca(3, 2, &RqPageMsg.(0, count), @sizeof(RqPageMsg))
} }
RlPageMsg := packed struct {a: u8, count: u8, ptr: ^u8} RlPageMsg := packed struct {a: u8, count: u8, ptr: ^u8}
release_page := fn(ptr: ^u8, count: u8): void { $release_page := fn(ptr: ^u8, count: u8): void {
return @eca(3, 2, &RlPageMsg.(1, count, ptr), @sizeof(RlPageMsg)) return @eca(3, 2, &RlPageMsg.(1, count, ptr), @sizeof(RlPageMsg))
} }
OutbMsg := packed struct {a: u8, b: u8, addr: u16, value: u8} OutbMsg := packed struct {a: u8, b: u8, addr: u16, value: u8}
outb := fn(addr: u16, value: u8): void { $outb := fn(addr: u16, value: u8): void {
return @eca(3, 3, &OutbMsg.(1, 0, addr, value), @sizeof(OutbMsg)) return @eca(3, 3, &OutbMsg.(1, 0, addr, value), @sizeof(OutbMsg))
} }
InbMsg := packed struct {a: u8, b: u8, addr: u16} InbMsg := packed struct {a: u8, b: u8, addr: u16}
inb := fn(addr: u16): u8 { $inb := fn(addr: u16): u8 {
return @eca(3, 3, &InbMsg.(0, 0, addr), @sizeof(InbMsg)) return @eca(3, 3, &InbMsg.(0, 0, addr), @sizeof(InbMsg))
} }
OutlMsg := packed struct {a: u8, b: u8, addr: u16, value: u32} OutlMsg := packed struct {a: u8, b: u8, addr: u16, value: u32}
outl := fn(addr: u16, value: u32): void { $outl := fn(addr: u16, value: u32): void {
return @eca(3, 3, &OutlMsg.(1, 2, addr, value), @sizeof(OutlMsg)) return @eca(3, 3, &OutlMsg.(1, 2, addr, value), @sizeof(OutlMsg))
} }
InlMsg := packed struct {a: u8, b: u8, addr: u16} InlMsg := packed struct {a: u8, b: u8, addr: u16}
inl := fn(addr: u16): u32 { $inl := fn(addr: u16): u32 {
return @eca(3, 3, &InlMsg.(0, 2, addr), @sizeof(InlMsg)) 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: u32, src: ^u8, dest: ^u8}
copy := fn($Expr: type, src: ^Expr, dest: ^Expr, count: uint): void { $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, @intcast(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: u32, size: u32, src: ^u8, dest: ^u8}
set := fn($Expr: type, src: ^Expr, dest: ^Expr, count: uint): void { $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, @intcast(count), @intcast(@sizeof(Expr)), @bitcast(src), @bitcast(dest)), @sizeof(SetMsg))
} }

View file

@ -3,5 +3,5 @@ any := fn($Expr: type): Expr {
} }
range := fn($Expr: type, min: Expr, max: Expr): Expr { range := fn($Expr: type, min: Expr, max: Expr): Expr {
return @inline(any, Expr) % (max - min) + @intcast(1) + min return *@eca(3, 4, &@as(Expr, idk), @sizeof(Expr)) % (max - min) + *@bitcast(&1) + min
} }

View file

@ -0,0 +1,6 @@
subscribe_to_interrupt := fn(interrupt_number: u8): bool {
return false
}
// Pauses execution until the interrupt occures
sleep_until_interrupt := fn(interrupt_number: u8): void {
}

View file

@ -4,118 +4,60 @@ length := fn(ptr: ^u8): uint {
} }
display_int := fn(num: int, p: ^u8, radix: uint): ^u8 { display_int := fn(num: int, p: ^u8, radix: uint): ^u8 {
is_negative := num < 0
if is_negative num = -num
ptr := p ptr := p
negative := num < 0
if negative {
num = -num
}
if radix == 2 {
*ptr = 48
ptr += 1;
*ptr = 98
ptr += 1
} else if radix == 16 {
*ptr = 48
ptr += 1;
*ptr = 120
ptr += 1
} else if radix == 8 {
*ptr = 48
ptr += 1;
*ptr = 111
ptr += 1
}
digits_start := ptr
if num == 0 { if num == 0 {
*ptr = 48 *ptr = 0x30;
ptr += 1 *(ptr + 1) = 0
} else { return p
loop if num == 0 break else {
digit := num % @bitcast(radix)
if digit < 10 {
*ptr = @intcast(digit) + 48
} else {
*ptr = @intcast(digit) + 55
}
ptr += 1
num /= @bitcast(radix)
}
} }
if negative { loop if num == 0 break else {
*ptr = 45 remainder := num % @bitcast(radix)
num /= @bitcast(radix);
*ptr = @intcast(remainder + 0x30)
if remainder > 9 {
*ptr = @intcast(remainder - 10 + 0x41)
}
ptr += 1 ptr += 1
}; }
*ptr = 0 if is_negative {
*ptr = 0x2D
@inline(reverse, digits_start) ptr += 1
}
// ! it gets broked when you do this ??
// *ptr = 0
@inline(reverse, p)
return p return p
} }
reverse := fn(s: ^u8): void { reverse := fn(s: ^u8): void {
i := 0 j := s + @inline(length, s) - 1
j := @inline(length, s) - 1
temp := @as(u8, 0) temp := @as(u8, 0)
loop if i >= j break else { loop if s < j {
temp = *(s + i); temp = *s;
*(s + i) = *(s + j); *s = *j;
*(s + j) = temp *j = temp
i += 1 s += 1
j -= 1 j -= 1
} } else return
return
} }
equals := fn(lhs: ^u8, rhs: ^u8): bool { equals := fn(lhs: ^u8, rhs: ^u8): bool {
if lhs == rhs { if lhs == rhs {
return true return true
} }
i := 0 loop if *lhs != *rhs {
loop if *(lhs + i) != *(rhs + i) {
return false return false
} else if *lhs == 0 { } else if *lhs == 0 {
return true return true
} else { } else {
i += 1 lhs += 1
rhs += 1
} }
} }
contains := fn(haystack: ^u8, needle: ^u8): bool {
haystack_len := @inline(length, haystack)
needle_len := @inline(length, needle)
if needle_len == 0 {
return true
}
if haystack_len < needle_len {
return false
}
max_start := haystack_len - needle_len
pos := 0
loop if pos > max_start break else {
is_match := true
offset := 0
loop if offset >= needle_len break else {
if *(haystack + pos + offset) != *(needle + offset) {
is_match = false
}
if is_match == false {
break
}
offset += 1
}
if is_match {
return true
}
pos += 1
}
return false
}

View file

@ -1,62 +1,63 @@
.{math: .{Vec2}, buffer, log, memory} := @use("../../stn/src/lib.hb"); .{math: .{Vec2}, buffer, log, memory, string} := @use("../../stn/src/lib.hb");
.{Surface, new_surface} := @use("../../render/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");
.{WindowWrapper, WindowID, WindowProps, WindowMessage, message, BUFFER} := @use("./lib.hb") .{new_surface, Color} := @use("../../render/src/lib.hb")
buffer_id := @as(?uint, null) // ! in the future this should be safely handled
channel := Channel.(0, 0)
new_window := fn(props: WindowProps): ?WindowWrapper { find_server := fn(): void {
if buffer_id == null { log.info("client: locating server\0")
log.error("client: (request_new) buffer id is null. did you init the client?\0") channel2 := await_channel()
return null channel.server = channel2.server
} channel.client = channel2.client
buf := memory.uninit(?WindowWrapper) log.info("client: server located\0")
buffer.write(WindowMessage, &.(message.new, 0, @sizeof(WindowProps), @bitcast(&props), @bitcast(&buf)), @unwrap(buffer_id))
loop if memory.is_uninit(?WindowWrapper, &buf) == false break else {
}
// loop until i write a better socket
i := 0
loop if i >= 1000 break else i += 1
return buf
} }
update_window_props := fn(wrapper: WindowWrapper): ?WindowProps { new := fn(props: WindowProps): ?Window {
log.error("todo: sunset_proto/src/client/update_window_props.hb\0") send_header(message.syn, channel.server)
if buffer_id == null { response := await_message(Channel, channel.client)
log.error("client: (request_update_properties) buffer id is null. did you init the client?\0") if response.header.kind != message.ack {
return null return null
} }
// TODO: buffer.write(WINDOWING_BUFFER, update properties) request log.info("client: recv ack\0")
return null send_message(WindowProps, message.props, props, response.body.server)
windowdata := await_message(WindowData, response.body.client)
if windowdata.header.kind != message.ack {
return null
}
log.info("client: recv windowdata\0")
surface := new_surface(windowdata.body.props.dimensions.x, windowdata.body.props.dimensions.y)
return .(windowdata.body, surface)
} }
request_shutdown := fn(): ?bool { quit := fn(client: Window): void {
if buffer_id == null { send_header(message.quit, client.data.channel.server)
log.error("client: (request_shutdown) buffer id is null. did you init the client?\0") }
return null
} connected := fn(client: Window): bool {
buf := memory.uninit(?u8) return true
buffer.write(WindowMessage, &.(message.shutdown, 0, 0, memory.dangling(u8), @bitcast(&buf)), @unwrap(buffer_id)) }
loop if memory.is_uninit(?u8, &buf) == false break else {
} shutdown_server := fn(client: Window): bool {
// loop until i write a better socket return false
i := 0 }
loop if i >= 1000 break else i += 1
// had to do ?u8 here, ?bool didnt work update_props := fn(client: Window): bool {
if buf == null | @unwrap(buf) != 255 { return false
}
update_permissions := fn(client: Window): bool {
return false
}
send_frame := fn(client: Window): bool {
send_header(message.frame_ready, client.data.channel.server)
response := await_message(uint, client.data.channel.client)
if response.header.kind != message.ack {
return false return false
} else {
return true
}
}
init := fn(): void {
log.info("client: waiting for server\0")
id := 0
loop if id != 0 {
buffer_id = id
log.info("client: done waiting\0")
return
} else {
id = buffer.search(BUFFER)
} }
// ! FOR NOW, server will ALWAYS be local,
// ! so we can send pointer to surface.
send_message(^Color, message.ack, client.surface.buf, client.data.channel.server)
return true
} }

View file

@ -1,36 +1,97 @@
.{math: .{Vec2}} := @use("../../stn/src/lib.hb"); .{math: .{Vec2}, buffer, memory} := @use("../../stn/src/lib.hb");
.{Surface} := @use("../../render/src/lib.hb") .{Surface} := @use("../../render/src/lib.hb")
$BUFFER := "sunset\0" $BUFFER_SERVER := "sunset_server\0"
$BUFFER_CLIENT := "sunset_client\0"
Channel := packed struct {
client: uint,
server: uint,
}
client := @use("./client.hb") client := @use("./client.hb")
server := @use("./server.hb") server := @use("./server.hb")
message := @use("./message.hb") message := @use("./message.hb")
permissions := @use("./permissions.hb")
WindowID := uint $send_message := fn($Expr: type, kind: MessageKind, msg: Expr, buffer_id: uint): void {
MessageKind := uint buffer.write(?Message(Expr), buffer_id, &@as(?Message(Expr), .(.(kind), msg)))
}
WindowMessage := packed struct { $send_header := fn(kind: MessageKind, buffer_id: uint): void {
buffer.write(?MessageHeader, buffer_id, &@as(?MessageHeader, .(kind)))
}
$recv_message := fn($Expr: type, buffer_id: uint): Message(Expr) {
response := @as(?Message(Expr), null)
buffer.recv(?Message(Expr), buffer_id, &response)
return response
}
$recv_header := fn(buffer_id: uint): ?MessageHeader {
response := @as(?MessageHeader, null)
buffer.recv(?MessageHeader, buffer_id, &response)
return response
}
await_channel := fn(): Channel {
channel := Channel.(0, 0)
loop if channel.server != 0 break else {
channel.server = buffer.search(BUFFER_SERVER)
}
loop if channel.client != 0 break else {
channel.client = buffer.search(BUFFER_CLIENT)
}
return channel
}
await_message := fn($Expr: type, buffer_id: uint): Message(Expr) {
response := @as(?Message(Expr), null)
loop {
buffer.recv(?Message(Expr), buffer_id, &response)
if response != null {
return @as(Message(Expr), response)
}
}
}
await_header := fn(buffer_id: uint): MessageHeader {
response := @as(?MessageHeader, null)
loop {
buffer.recv(?MessageHeader, buffer_id, &response)
if response != null {
return @as(?MessageHeader, response)
}
}
}
MessageKind := u8
MessageHeader := packed struct {
kind: MessageKind, kind: MessageKind,
id: WindowID, }
length: uint,
data_ptr: ^u8, Message := fn($Expr: type): type {
// need to replace this with a buffer id return packed struct {
callback: ^u8, header: MessageHeader,
body: Expr,
}
} }
WindowProps := struct { WindowProps := struct {
position: Vec2(uint), position: Vec2(uint),
dimensions: Vec2(uint), dimensions: Vec2(uint),
// ! replace with owned string type later
title: ^u8, title: ^u8,
} }
WindowWrapper := struct { WindowData := struct {
id: WindowID,
props: WindowProps, props: WindowProps,
channel: Channel,
permissions: uint,
} }
Window := struct { Window := struct {
data: WindowData,
surface: Surface, surface: Surface,
props: WindowProps,
} }

View file

@ -1,4 +1,8 @@
$new := 0 // ! all values in this file are subject to change.
$destroy := 1 $syn := 1
$update_props := 2 $ack := 2
$shutdown := 3 $refused := 3
$quit := 4
$props := 5
$shutdown := 6
$frame_ready := 7

View file

@ -0,0 +1,5 @@
$none := 0b0
$exclusive_framebuffer := 0b1
$shutdown := 0b100
$default := none

View file

@ -1,34 +1,135 @@
.{math, log, string, random, buffer, memory} := @use("../../stn/src/lib.hb"); .{math, log, string, random, buffer, memory} := @use("../../stn/src/lib.hb");
.{Surface, new_surface} := @use("../../render/src/lib.hb"); .{Color, Surface, new_surface, put_surface, sync, put_rect, put_filled_rect, text, put_text, clear, white, black} := @use("../../render/src/lib.hb");
.{WindowWrapper, WindowID, WindowProps, WindowMessage, BUFFER} := @use("./lib.hb") .{Channel, Window, WindowProps, WindowData, MessageHeader, BUFFER_SERVER, BUFFER_CLIENT, message, permissions, recv_header, recv_message, send_message, send_header, await_message} := @use("./lib.hb")
WindowServer := struct {window_count: uint, buffer_id: uint} WindowServer := struct {
window_count: uint,
server := @as(?WindowServer, null) channel: Channel,
// ! replace this with a collection when we get an allocator
new_window_id := fn(): WindowID { windows: [?Window; 10],
return random.any(uint) font: text.Font,
} }
init := fn(): bool { // ! in the future this should be safely handled
log.info("server: starting server\0") server := @as(WindowServer, idk)
server = .(0, buffer.create(BUFFER))
psf := @embed("../../../assets/consolefonts/tamsyn/10x20r.psf")
start := fn(): void {
font := text.font_from_psf2(@bitcast(&psf), false)
if font == null {
log.error("server: failed to load asset\0")
return
}
server = .(
0,
.{client: buffer.create(BUFFER_CLIENT), server: buffer.create(BUFFER_SERVER)},
.(null, null, null, null, null, null, null, null, null, null),
@as(text.Font, font),
)
log.info("server: started server\0")
}
incoming := fn(): bool {
msg := recv_header(server.channel.server)
if msg == null {
return true
}
if msg.kind == message.syn {
log.info("server: recv syn\0")
channel := Channel.(buffer.create_nameless(), buffer.create_nameless())
send_message(Channel, message.ack, channel, server.channel.client)
props := await_message(WindowProps, channel.server)
if props.header.kind != message.props {
return true
}
log.info("server: recv props\0")
// ! do inspection of requested props here
data := WindowData.(props.body, channel, permissions.default)
send_message(WindowData, message.ack, data, channel.client)
surface := new_window_decorations(data.props.dimensions)
// decorations
{
title := data.props.title
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)
// Draw the window tab
put_filled_rect(surface, .(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)
put_text(surface, server.font, .(2, 1), .(0, 0, 0, 255), data.props.title)
}
server.windows[server.window_count] = .(data, surface)
server.window_count += 1
}
return true return true
} }
recieve := fn(): ?WindowMessage { $DECO_WIDTH := 2
if server == null { $DECO_HEIGHT_TOP := 20
log.error("server: (request_new) server is null. did you init the client?\0") $DECO_HEIGHT_BOTTOM := 1
return null $DECO_COLOUR := Color.(100, 200, 255, 255)
} $DECO_COLOUR_DARKER := Color.(89, 57, 89, 255)
buf := memory.uninit(WindowMessage)
buffer.recv(WindowMessage, @unwrap(server).buffer_id, @bitcast(&buf)) new_window_decorations := fn(dimensions: math.Vec2(uint)): Surface {
if memory.is_uninit(WindowMessage, &buf) { return new_surface(
return null dimensions.x + DECO_WIDTH,
} dimensions.y + DECO_HEIGHT_TOP + DECO_HEIGHT_BOTTOM,
return buf )
} }
should_shutdown := fn(): bool { // ! compositor code. this currently disallows tearing.
return false
collect_frames := fn(): void {
i := 0
loop if i == 10 break else {
window := server.windows[i]
if window == null {
i += 1
continue
}
header := recv_header(window.data.channel.server)
if header == null {
i += 1
continue
}
if header.kind != message.frame_ready {
i += 1
continue
}
send_header(message.ack, window.data.channel.client)
ptr := await_message(^Color, window.data.channel.server)
if ptr.header.kind != message.ack {
return
}
put_surface(
window.surface,
Surface.(
ptr.body,
window.data.props.dimensions.x,
window.data.props.dimensions.y,
window.data.props.dimensions.x * window.data.props.dimensions.y,
),
.(DECO_WIDTH / 2, DECO_HEIGHT_TOP),
false,
)
i += 1
}
}
render_clients := fn(screen: Surface): void {
i := 0
loop if i == 10 break else {
window := server.windows[i]
if window == null {
i += 1
continue
}
put_surface(screen, window.surface, window.data.props.position, false)
i += 1
}
} }

View file

@ -56,23 +56,13 @@ main := fn(): int {
loop { loop {
// Clear the screen // Clear the screen
render.clear(screen, render.black) render.clear(screen, render.black)
render.put_surface(screen, wallpaper, .(0, 0), false) render.put_surface(screen, wallpaper, .(0, 0), false)
// TODO: Read the window buffer here // TODO: Read the window buffer here
{ {
// buffer.recv([u8; 4096], win_buff, mem_buf)
// // for some reason this null check causes the compiler to spin forever
// if *mem_buf == 0 {
// log.info("No messages\0")
// } else {
// log.info("Handle Messages\0")
// }
} }
// get input events from drivers via intouch
// key_event := intouch.recieve_key_event();
// log.info("before mouse event check\0");
if false { if false {
// Scroll bar :ThumbsUp: // Scroll bar :ThumbsUp:
render.put_rect(screen, .(100, 100), .(100, 10), render.white) render.put_rect(screen, .(100, 100), .(100, 10), render.white)
@ -82,6 +72,12 @@ main := fn(): int {
render.put_filled_rect(screen, .(90, 120), .(10, 20), render.white) render.put_filled_rect(screen, .(90, 120), .(10, 20), render.white)
} }
{
// osu dots
render.put_rect(screen, .(400, 100), .(100, 100), render.red)
render.put_rect(screen, .(100, 100 + 300), .(100, 100), render.red)
}
{ {
pos := Vec2(uint).(1, screen.height - 21) pos := Vec2(uint).(1, screen.height - 21)
render_label_to_surface(screen, text_label, font, pos) render_label_to_surface(screen, text_label, font, pos)
@ -91,12 +87,20 @@ main := fn(): int {
// Screen border // Screen border
render.put_rect(screen, .(0, 0), .(screen.width - 1, screen.height - 1), render.white) render.put_rect(screen, .(0, 0), .(screen.width - 1, screen.height - 1), render.white)
// get input events from drivers via intouch
if false {
key_event := intouch.recieve_key_event()
if key_event != null {
log.info("Key event \0")
}
}
{ {
mouse_event := intouch.recieve_mouse_event() mouse_event := intouch.recieve_mouse_event()
// //
if mouse_event != null { if mouse_event != null {
// log.warn("Mouse event recieved\0") // log.warn("Mouse event received\0")
change_x := @as(i16, mouse_event.x_change) change_x := @as(i16, mouse_event.x_change)
change_x = change_x << 8 change_x = change_x << 8
@ -133,13 +137,9 @@ main := fn(): int {
} }
} }
// render mouse render.put_filled_rect(screen, .(mouse_x, mouse_y), .(20, 20), render.black)
lum := render.indexptr(screen, mouse_x, mouse_y) render.put_rect(screen, .(mouse_x, mouse_y), .(20, 20), render.white)
if lum.r / 3 + lum.g / 3 + lum.b / 3 < 128 {
render.put_rect(screen, .(mouse_x, mouse_y), .(20, 20), render.white)
} else {
render.put_rect(screen, .(mouse_x, mouse_y), .(20, 20), render.black)
}
// Send events to focused window // Send events to focused window
} }

View file

@ -1,4 +1,8 @@
.{memory, log, buffer} := @use("../../../libraries/stn/src/lib.hb") stn := @use("../../../libraries/stn/src/lib.hb");
.{memory, log, buffer} := stn
intouch := @use("../../../libraries/intouch/src/lib.hb");
.{KeyEvent} := intouch
send_byte := fn(byte: u8): u8 { send_byte := fn(byte: u8): u8 {
memory.outb(96, byte) memory.outb(96, byte)
@ -6,23 +10,31 @@ send_byte := fn(byte: u8): u8 {
} }
main := fn(): int { main := fn(): int {
buf := buffer.create("XKeyboard\0") buf := buffer.create("PS/2 Keyboard\0")
_ = send_byte(238) _ = send_byte(238)
log.info("PS/2 Driver Loaded\0") log.info("PS/2 Driver Loaded\0")
if send_byte(238) == 238 { if send_byte(238) == 238 {
log.info("PS/2 Keyboard Echoed\0") log.info("PS/2 Keyboard Echoed\0")
} }
if send_byte(244) == 250 { if send_byte(244) == 250 {
log.info("Enabled scanning\0") log.info("Enabled scanning\0")
} }
prev_input := 250 prev_input := 250
loop { loop {
loop if (memory.inb(0x64) & 0x20) == 0x20 break
input := memory.inb(96) input := memory.inb(96)
if input == prev_input { if input == prev_input {
continue continue
} }
prev_input = input prev_input = input
buffer.write(u8, &input, buf) kevent := KeyEvent.(false, true, input)
buffer.write(KeyEvent, buf, &kevent)
} }
return 0 return 0
} }

View file

@ -145,7 +145,7 @@ main := fn(): int {
event.x_change = x_change event.x_change = x_change
event.y_change = y_change event.y_change = y_change
buffer.write(MouseEvent, &event, mouse_buffer) buffer.write(MouseEvent, mouse_buffer, &event)
} }
return 0 return 0

View file

@ -10,12 +10,12 @@ example := fn(): void {
color := render.light_cyan color := render.light_cyan
n := @as(u8, 1) n := @as(u8, 1)
loop { loop {
// ! dead code elimination bug
render.clear(screen, color) render.clear(screen, color)
render.sync(screen) render.sync(screen)
if (color.b & 255) == 255 | (color.b & 255) == 0 { if color.b == 255 | color.b == 0 {
n = -n n = -n
} }
color.b += n color.b += n
} }
return
} }

View file

@ -46,7 +46,7 @@ example := fn(): void {
bottom := buf + msg_len bottom := buf + msg_len
@inline(memory.copy, u8, msg, buf, msg_len) memory.copy(u8, msg, buf, msg_len)
cursor := bottom cursor := bottom
draw_window(window, font, buf, cursor) draw_window(window, font, buf, cursor)

View file

@ -1 +1 @@
.{example: main} := @use("./examples/orbit.hb") .{example: main} := @use("./examples/text.hb")

View file

@ -1,24 +1,29 @@
.{log, string} := @use("../../../libraries/stn/src/lib.hb") .{log} := @use("../../../libraries/stn/src/lib.hb")
sunset := @use("../../../libraries/sunset_proto/src/lib.hb") sunset := @use("../../../libraries/sunset_proto/src/lib.hb")
render := @use("../../../libraries/render/src/lib.hb")
bmp := @embed("../../../assets/mini.bmp")
main := fn(): void { main := fn(): void {
sunset.client.init() sunset.client.find_server()
log.info("client: request new window\0")
window := sunset.client.new_window(.(.(100, 100), .(150, 150), "Hello, World!\0")) image := render.image.bmp.from(@bitcast(&bmp))
if window == null { if image == null {
log.error("Could not create window\0") log.error("got no image\0")
return return
} }
log.info("client: window created. title:\0")
log.info(window.props.title) window := sunset.client.new(.(.(100, 100), .(200, 200), "Hello,\0"))
window.props.position = .(500, 500)
props := @unwrap(sunset.client.update_window_props(window)) if window == null {
if props.position.x != window.props.position.x { log.error("got no window\0")
log.error("client: we did not update props\0") return
} }
log.info("client: sending shutdown request\0") x := 0
shutdown := sunset.client.request_shutdown() loop {
if shutdown == null { render.clear(window.surface, render.black)
log.error("client: didnt shutdown the server\0") render.put_surface(window.surface, image, .(image.width + x % window.data.props.dimensions.x, 20), false)
_ = sunset.client.send_frame(window)
x += 1
} }
} }

View file

@ -0,0 +1,11 @@
[package]
name = "sunset_client_2"
authors = ["koniifer"]
[dependants.libraries]
[dependants.binaries]
hblang.version = "1.0.0"
[build]
command = "hblang src/main.hb"

View file

@ -0,0 +1,29 @@
.{log} := @use("../../../libraries/stn/src/lib.hb")
sunset := @use("../../../libraries/sunset_proto/src/lib.hb")
render := @use("../../../libraries/render/src/lib.hb")
bmp := @embed("../../../assets/able.bmp")
main := fn(): void {
sunset.client.find_server()
image := render.image.bmp.from(@bitcast(&bmp))
if image == null {
log.error("got no image\0")
return
}
window := sunset.client.new(.(.(400, 300), .(400, 240), "Sunset!\0"))
if window == null {
log.error("got no window\0")
return
}
x := 0
loop {
render.clear(window.surface, render.black)
render.put_surface(window.surface, image, .(image.width + x % window.data.props.dimensions.x, 40), false)
_ = sunset.client.send_frame(window)
x += 1
}
}

View file

@ -1,36 +1,98 @@
.{log} := @use("../../../libraries/stn/src/lib.hb") sunset := @use("../../../libraries/sunset_proto/src/lib.hb")
render := @use("../../../libraries/render/src/lib.hb"); render := @use("../../../libraries/render/src/lib.hb")
.{server, message, WindowWrapper, WindowProps} := @use("../../../libraries/sunset_proto/src/lib.hb") intouch := @use("../../../libraries/intouch/src/lib.hb")
horizon_api := @use("../../../libraries/horizon_api/src/lib.hb");
.{new_label, render_label_to_surface, set_label_text} := horizon_api.widgets.label
stn := @use("../../../libraries/stn/src/lib.hb");
.{Vec2} := stn.math
psf := @embed("../../../assets/consolefonts/tamsyn/10x20r.psf") psf := @embed("../../../assets/consolefonts/tamsyn/10x20r.psf")
img := @embed("../../../assets/wallpaper.qoi")
main := fn(): void { main := fn(): int {
screen := render.init(false) sunset.server.start()
font := render.text.font_from_psf2(@bitcast(&psf), false)
if font == null { screen := render.init(true)
return render.clear(screen, render.black)
font := @unwrap(render.text.font_from_psf2(@bitcast(&psf), false))
wallpaper := render.image.from(@bitcast(&img))
if wallpaper == null {
// stn.panic("Wallpaper not loaded\0")
return 1
} }
if server.init() == false {
log.error("Failed to create server\0") mouse_x := 100
return mouse_y := 100
}
loop if server.should_shutdown() break else { text_label := new_label("Hi\0")
recv := server.recieve()
if recv == null { loop {
continue mouse_event := intouch.recieve_mouse_event()
} else if recv.kind == message.new { if mouse_event != null {
props := *@as(^WindowProps, @bitcast(recv.data_ptr)); change_x := @as(i16, mouse_event.x_change)
*@as(^?WindowWrapper, @bitcast(recv.callback)) = WindowWrapper.(0, props) change_x = change_x << 8
render.put_rect(screen, props.position, props.dimensions, render.white) change_x = change_x >> 8
render.put_text(screen, font, props.position + .(1, 1), render.white, props.title)
render.put_hline(screen, props.position.y + font.height + 2, props.position.x, props.position.x + props.dimensions.x, render.white) mouse_x += change_x
log.info("server: made a new window\0") if mouse_x < 0 {
} else if recv.kind == message.shutdown { mouse_x = 0
*@as(^?u8, @bitcast(recv.callback)) = 255 }
break if mouse_x >= screen.width - 20 {
mouse_x = @intcast(screen.width - 21)
}
change_y := @as(i16, mouse_event.y_change)
change_y = change_y << 8
change_y = change_y >> 8
if mouse_y < 0 {
mouse_y = 0
}
if mouse_y >= screen.height - 20 {
mouse_y = @intcast(screen.height - 21)
}
mouse_y -= change_y
if mouse_event.left {
set_label_text(text_label, "LEFT CLICK\0")
}
if mouse_event.middle {
set_label_text(text_label, "MIDDLE CLICK\0")
}
if mouse_event.right {
set_label_text(text_label, "RIGHT CLICK\0")
}
} }
{
render.clear(screen, render.black)
render.put_surface(screen, wallpaper, .(0, 0), false)
render.put_rect(screen, .(0, 0), .(screen.width - 1, screen.height - 1), sunset.server.DECO_COLOUR)
}
if sunset.server.incoming() {
sunset.server.collect_frames()
sunset.server.render_clients(screen)
}
{
pos := Vec2(uint).(1, screen.height - 21)
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)
}
// Mouse cursor
{
render.put_filled_rect(screen, .(mouse_x, mouse_y), .(20, 20), sunset.server.DECO_COLOUR_DARKER)
render.put_rect(screen, .(mouse_x, mouse_y), .(20, 20), sunset.server.DECO_COLOUR)
}
render.sync(screen)
} }
render.put_text(screen, font, .(0, 0), render.white, "Shutdown triggered\0") return 0
log.info("Server shutdown\0")
} }

View file

@ -28,8 +28,8 @@ resolution = "1024x768x24"
# [boot.limine.ableos.modules.horizon] # [boot.limine.ableos.modules.horizon]
# path = "boot:///horizon.hbf" # path = "boot:///horizon.hbf"
# [boot.limine.ableos.modules.ps2_mouse_driver] [boot.limine.ableos.modules.ps2_mouse_driver]
# path = "boot:///ps2_mouse_driver.hbf" path = "boot:///ps2_mouse_driver.hbf"
# [boot.limine.ableos.modules.ps2_keyboard_driver] # [boot.limine.ableos.modules.ps2_keyboard_driver]
# path = "boot:///ps2_keyboard_driver.hbf" # path = "boot:///ps2_keyboard_driver.hbf"

View file

@ -19,12 +19,14 @@
@morshy @morshy
Simple Userland Allocator Simple Userland Allocator
@funky
Kernel Testing Framework (A rust framework for testing the kernel)
@unassigned @unassigned
FileIO (Fat32) FileIO (Fat32)
DiskIO (Undecided Disk type) DiskIO (Undecided Disk type)
Proper Memory Protection Proper Memory Protection
Channels (Two buffers bundled together to form two way communication) Channels (Two buffers bundled together to form two way communication)
Kernel Testing Framework (A rust framework for testing the kernel)
Userland Testing Framework (An hblang framework for testing the userspace) Userland Testing Framework (An hblang framework for testing the userspace)
PCI/E (Honestly I have no fucking clue whats going on with PCI or why userland cant properly read it) PCI/E (Honestly I have no fucking clue whats going on with PCI or why userland cant properly read it)
Kernel Reimpl (Do not you dare think about this yet its only here as an option to show goals) Kernel Reimpl (Do not you dare think about this yet its only here as an option to show goals)