Litrally amlmost functional PS/2 driver. #19
10
Cargo.lock
generated
10
Cargo.lock
generated
|
@ -82,9 +82,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
|||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.2.0"
|
||||
version = "1.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1aeb932158bd710538c73702db6945cb68a8fb08c519e6e12706b94263b36db8"
|
||||
checksum = "fd9de9f2205d5ef3fd67e685b0df337994ddd4495e2a28d185500d0e1edfea47"
|
||||
dependencies = [
|
||||
"shlex",
|
||||
]
|
||||
|
@ -228,12 +228,12 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "hbbytecode"
|
||||
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]]
|
||||
name = "hblang"
|
||||
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 = [
|
||||
"hashbrown 0.15.1",
|
||||
"hbbytecode",
|
||||
|
@ -245,7 +245,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "hbvm"
|
||||
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 = [
|
||||
"hbbytecode",
|
||||
]
|
||||
|
|
|
@ -11,6 +11,7 @@ static mut LAPIC: LocalApic = unsafe { MaybeUninit::zeroed().assume_init() };
|
|||
static mut IDT: InterruptDescriptorTable = unsafe { MaybeUninit::zeroed().assume_init() };
|
||||
|
||||
#[repr(u8)]
|
||||
#[derive(Debug)]
|
||||
enum Interrupt {
|
||||
Timer = 32,
|
||||
ApicErr = u8::MAX - 1,
|
||||
|
@ -66,11 +67,20 @@ extern "x86-interrupt" fn timer(_isf: InterruptStackFrame) {
|
|||
}
|
||||
|
||||
extern "x86-interrupt" fn apic_err(_: InterruptStackFrame) {
|
||||
interrupt(Interrupt::ApicErr);
|
||||
|
||||
panic!("Internal APIC error");
|
||||
}
|
||||
|
||||
extern "x86-interrupt" fn spurious(_: InterruptStackFrame) {
|
||||
interrupt(Interrupt::Spurious);
|
||||
|
||||
unsafe {
|
||||
LAPIC.end_of_interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
fn interrupt(interrupt_type: Interrupt){
|
||||
log::info!("Interrupt type {:?}", interrupt_type);
|
||||
panic!()
|
||||
}
|
|
@ -111,7 +111,7 @@ unsafe extern "C" fn oops() -> ! {
|
|||
unsafe extern "C" fn start() -> ! {
|
||||
logging::init();
|
||||
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);
|
||||
memory::init_pt(VirtAddr::new(
|
||||
|
@ -190,7 +190,7 @@ unsafe extern "C" fn start() -> ! {
|
|||
// TODO: Add in rdseed and rdrand as sources for randomness
|
||||
let _rand = xml::XMLElement::new("Random");
|
||||
|
||||
log::trace!("Getting boot modules");
|
||||
log::debug!("Getting boot modules");
|
||||
let bm = MOD_REQ.get_response().get();
|
||||
|
||||
let mut bootmodules = alloc::vec::Vec::new();
|
||||
|
@ -228,7 +228,7 @@ unsafe extern "C" fn start() -> ! {
|
|||
break;
|
||||
}
|
||||
}
|
||||
log::info!("Boot module count: {:?}", bootmodules.len());
|
||||
log::debug!("Boot module count: {:?}", bootmodules.len());
|
||||
assert_eq!(bm.module_count, bootmodules.len() as u64);
|
||||
}
|
||||
|
||||
|
|
|
@ -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) };
|
||||
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 pci_class = PciFullClass::from_u16(class);
|
||||
let header_type = get_header_type(bus, device, 0);
|
||||
|
|
|
@ -58,10 +58,10 @@ pub fn handler(vm: &mut Vm) {
|
|||
true => IpcBuffer::new(true, length),
|
||||
},
|
||||
);
|
||||
info!("Buffer ID: {}", buff_id);
|
||||
vm.registers[1] = hbvm::value::Value(buff_id);
|
||||
}
|
||||
2 => {
|
||||
log::error!("Oops, deleting buffers is not implemented.")
|
||||
// Delete buffer
|
||||
}
|
||||
3 => {
|
||||
|
@ -182,7 +182,7 @@ pub fn handler(vm: &mut Vm) {
|
|||
} else {
|
||||
unsafe {
|
||||
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);
|
||||
|
|
|
@ -9,7 +9,20 @@ use log::Record;
|
|||
pub fn log_msg_handler(_vm: &mut Vm, mem_addr: u64, length: usize) -> Result<(), LogError> {
|
||||
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 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) {
|
||||
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(
|
||||
&Record::builder()
|
||||
.args(format_args!("{}", strr))
|
||||
|
|
|
@ -25,42 +25,16 @@ fn alloc_page(vm: &mut Vm, _mem_addr: u64, _length: usize) -> Result<(), MemoryS
|
|||
}
|
||||
|
||||
#[inline(always)]
|
||||
unsafe fn memset(mut dest: *mut u8, src: *const u8, count: usize, size: usize) {
|
||||
const BLOCK_SIZE: usize = 64;
|
||||
let mut remaining = count * size;
|
||||
unsafe fn memset(dest: *mut u8, src: *const u8, count: usize, size: usize) {
|
||||
let total_size = count * size;
|
||||
src.copy_to_nonoverlapping(dest, size);
|
||||
|
||||
if remaining < 16 {
|
||||
src.copy_to_nonoverlapping(dest, remaining);
|
||||
return;
|
||||
}
|
||||
let mut copied = size;
|
||||
|
||||
let mut buffer = [0u8; BLOCK_SIZE];
|
||||
let mut buffer_size = size;
|
||||
src.copy_to_nonoverlapping(buffer.as_mut_ptr(), 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);
|
||||
while copied < total_size {
|
||||
let copy_size = copied.min(total_size - copied);
|
||||
dest.add(copied).copy_from_nonoverlapping(dest, copy_size);
|
||||
copied += copy_size;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -71,7 +71,18 @@ pub fn kmain(_cmdline: &str, boot_modules: BootModules) -> ! {
|
|||
let cmd = module.cmd.trim_matches('"');
|
||||
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
|
||||
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 data_length = u64::from_le_bytes(header[15..23].try_into().unwrap());
|
||||
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));
|
||||
if cmd_len > 0 {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#![allow(unused)]
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
fmt::format,
|
||||
fs::{read_to_string, File},
|
||||
io::{BufWriter, Write},
|
||||
|
@ -13,6 +14,7 @@ pub struct Package {
|
|||
name: String,
|
||||
binaries: Vec<String>,
|
||||
build_cmd: String,
|
||||
args: HashMap<String, String>,
|
||||
}
|
||||
|
||||
impl Package {
|
||||
|
@ -46,26 +48,32 @@ impl Package {
|
|||
let mut binaries = vec![];
|
||||
|
||||
for (count, (name, table)) in bin_table.into_iter().enumerate() {
|
||||
// if count != 0 {
|
||||
binaries.push(name.clone());
|
||||
// }
|
||||
}
|
||||
let build_table = data.get("build").unwrap();
|
||||
|
||||
let mut build_cmd: String = build_table.get("command").unwrap().as_str().unwrap().into();
|
||||
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 {
|
||||
name,
|
||||
binaries,
|
||||
build_cmd,
|
||||
args,
|
||||
}
|
||||
}
|
||||
pub fn build(&self, out: &mut Vec<u8>) -> std::io::Result<()> {
|
||||
if self.binaries.contains(&"hblang".to_string()) {
|
||||
let file = self.build_cmd.split_ascii_whitespace().last().unwrap();
|
||||
|
||||
let path = format!("sysdata/programs/{}/{}", self.name, file);
|
||||
// compile here
|
||||
|
||||
|
@ -73,6 +81,7 @@ impl Package {
|
|||
&path,
|
||||
Options {
|
||||
fmt: true,
|
||||
in_house_regalloc: true,
|
||||
..Default::default()
|
||||
},
|
||||
out,
|
||||
|
@ -87,6 +96,7 @@ impl Package {
|
|||
hblang::run_compiler(
|
||||
&path,
|
||||
Options {
|
||||
in_house_regalloc: true,
|
||||
..Default::default()
|
||||
},
|
||||
out,
|
||||
|
@ -98,6 +108,7 @@ impl Package {
|
|||
&path,
|
||||
Options {
|
||||
dump_asm: true,
|
||||
in_house_regalloc: true,
|
||||
..Default::default()
|
||||
},
|
||||
out,
|
||||
|
|
|
@ -1,13 +1,9 @@
|
|||
keycodes := @use("keycodes.hb");
|
||||
.{KeyCode} := keycodes
|
||||
|
||||
KeyEvent := struct {
|
||||
// 0 if down
|
||||
// 1 if up
|
||||
up: u8,
|
||||
// 0 if not just triggered
|
||||
// 1 if just triggered
|
||||
just_triggered: u8,
|
||||
KeyEvent := packed struct {
|
||||
up: bool,
|
||||
just_triggered: bool,
|
||||
key: KeyCode,
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,17 @@ events := @use("events.hb");
|
|||
.{KeyEvent, MouseEvent} := events
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
|
@ -15,7 +26,7 @@ recieve_mouse_event := fn(): ?MouseEvent {
|
|||
buf_id := buffer.search("PS/2 Mouse\0")
|
||||
|
||||
// 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 {
|
||||
return mevent
|
||||
|
|
|
@ -1,7 +1,4 @@
|
|||
# Images
|
||||
- General over image format
|
||||
- Support formats:
|
||||
- PNG
|
||||
- Animation
|
||||
|
||||
# API
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
.{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 {
|
||||
magic: u16,
|
||||
|
@ -41,7 +41,7 @@ from := fn(bmp: ^u8): ?Surface {
|
|||
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)
|
||||
put_surface(rhs, lhs, .(0, 0), true)
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
.{Color, Surface, new_surface} := @use("../lib.hb");
|
||||
.{log, memory} := @use("../../../stn/src/lib.hb")
|
||||
.{log} := @use("../../../stn/src/lib.hb")
|
||||
|
||||
/* source:
|
||||
https://github.com/phoboslab/qoi/blob/master/qoi.h */
|
||||
|
@ -13,7 +13,7 @@ $QOI_OP_RUN := 0xC0
|
|||
$QOI_OP_RGB := 0xFE
|
||||
$QOI_OP_RGBA := 0xFF
|
||||
$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
|
||||
}
|
||||
$QOI_MAGIC := 0x716F6966
|
||||
|
@ -89,7 +89,7 @@ from := fn(qoi: ^u8): ?Surface {
|
|||
run = b1 & 0x3F
|
||||
}
|
||||
|
||||
index[@inline(QOI_COLOR_HASH, px)] = px
|
||||
index[QOI_COLOR_HASH(px)] = px
|
||||
};
|
||||
|
||||
*(surface.buf + px_pos) = px
|
||||
|
|
|
@ -10,19 +10,21 @@ Surface := struct {
|
|||
buf: ^Color,
|
||||
width: uint,
|
||||
height: uint,
|
||||
size: uint,
|
||||
}
|
||||
|
||||
new_surface := fn(width: uint, height: uint): Surface {
|
||||
return .(
|
||||
@inline(memory.alloc, Color, width * height),
|
||||
memory.alloc(Color, width * height),
|
||||
width,
|
||||
height,
|
||||
width * height,
|
||||
)
|
||||
}
|
||||
|
||||
clone_surface := fn(surface: ^Surface): Surface {
|
||||
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
|
||||
}
|
||||
|
||||
|
@ -33,42 +35,38 @@ init := fn(doublebuffer: bool): Surface {
|
|||
if doublebuffer {
|
||||
return new_surface(width, height)
|
||||
} else {
|
||||
return .(framebuffer, width, height)
|
||||
return .(framebuffer, width, height, width * height)
|
||||
}
|
||||
}
|
||||
|
||||
clear := fn(surface: Surface, color: Color): void {
|
||||
return @inline(memory.set, Color, &color, surface.buf, surface.width * surface.height)
|
||||
$clear := fn(surface: Surface, color: Color): void {
|
||||
memory.set(Color, &color, surface.buf, surface.width * surface.height)
|
||||
}
|
||||
|
||||
sync := fn(surface: Surface): void {
|
||||
if surface.buf == framebuffer {
|
||||
return
|
||||
}
|
||||
return @inline(memory.copy, Color, surface.buf, framebuffer, @bitcast(surface.width * surface.height))
|
||||
$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 {
|
||||
$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 + @inline(index, surface, x, 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 {
|
||||
*@inline(indexptr, surface, pos.x, pos.y) = color
|
||||
return
|
||||
$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 := @inline(indexptr, surface, pos.x, pos.y)
|
||||
bottom_start_idx := @inline(indexptr, surface, pos.x, pos.y + tr.y - 1)
|
||||
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 {
|
||||
@inline(memory.set, Color, &color, top_start_idx, tr.x)
|
||||
@inline(memory.set, Color, &color, bottom_start_idx, tr.x)
|
||||
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
|
||||
|
@ -76,16 +74,16 @@ put_filled_rect := fn(surface: Surface, pos: Vec2(uint), tr: Vec2(uint), color:
|
|||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
put_rect := fn(surface: Surface, pos: Vec2(uint), tr: Vec2(uint), color: Color): void {
|
||||
start_idx := @inline(indexptr, surface, pos.x, pos.y)
|
||||
end_idx := @inline(indexptr, surface, pos.x, pos.y + tr.y)
|
||||
right_start_idx := @inline(indexptr, surface, pos.x + tr.x, pos.y)
|
||||
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;
|
||||
|
@ -94,8 +92,8 @@ put_rect := fn(surface: Surface, pos: Vec2(uint), tr: Vec2(uint), color: Color):
|
|||
right_start_idx += surface.width
|
||||
}
|
||||
|
||||
@inline(memory.set, Color, &color, @inline(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), @bitcast(tr.x + 1))
|
||||
memory.set(Color, &color, indexptr(surface, pos.x, pos.y + tr.y), @bitcast(tr.x + 1))
|
||||
|
||||
return
|
||||
}
|
||||
|
@ -112,7 +110,7 @@ put_line_low := fn(surface: Surface, p0: Vec2(uint), p1: Vec2(uint), color: Colo
|
|||
y := p0.y
|
||||
x := p0.x
|
||||
loop if x == p1.x break else {
|
||||
*@inline(indexptr, surface, x, y) = color
|
||||
*indexptr(surface, x, y) = color
|
||||
if D > 0 {
|
||||
y += yi
|
||||
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
|
||||
y := p0.y
|
||||
loop if y == p1.y break else {
|
||||
*@inline(indexptr, surface, x, y) = color
|
||||
*indexptr(surface, x, y) = color
|
||||
if D > 0 {
|
||||
x += xi
|
||||
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_bottom_cursor := top.buf + top.width * (top.height - 1)
|
||||
|
||||
dst_top_idx := @inline(indexptr, surface, pos.x, pos.y)
|
||||
dst_bottom_idx := @inline(indexptr, surface, pos.x, pos.y + 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_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
|
||||
|
||||
loop if rows_to_copy <= 1 break else {
|
||||
@inline(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_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
|
||||
|
@ -195,7 +193,7 @@ put_surface := fn(surface: Surface, top: Surface, pos: Vec2(uint), flip_v: bool)
|
|||
}
|
||||
|
||||
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
|
||||
|
@ -233,7 +231,7 @@ put_vline := fn(surface: Surface, x: uint, y0: uint, y1: uint, color: Color): vo
|
|||
y := y0
|
||||
|
||||
loop if y == y1 break else {
|
||||
*@inline(indexptr, surface, x, y) = color
|
||||
*indexptr(surface, x, y) = color
|
||||
y += 1
|
||||
}
|
||||
|
||||
|
@ -247,7 +245,8 @@ put_hline := fn(surface: Surface, y: uint, x0: uint, x1: uint, color: Color): vo
|
|||
x0 = x1
|
||||
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
|
||||
}
|
||||
|
@ -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 {
|
||||
x := 0
|
||||
y := radius
|
||||
error := @as(int, 3) - @as(int, @intcast(2 * radius));
|
||||
*@inline(indexptr, surface, pos.x + radius, pos.y) = color;
|
||||
*@inline(indexptr, surface, pos.x - radius, pos.y) = color;
|
||||
*@inline(indexptr, surface, pos.x, pos.y + radius) = color;
|
||||
*@inline(indexptr, surface, pos.x, pos.y - radius) = color
|
||||
error := @as(int, 3) - @intcast(2 * radius);
|
||||
*indexptr(surface, pos.x + radius, pos.y) = color;
|
||||
*indexptr(surface, pos.x - radius, pos.y) = color;
|
||||
*indexptr(surface, pos.x, pos.y + radius) = color;
|
||||
*indexptr(surface, pos.x, pos.y - radius) = color
|
||||
|
||||
loop if y < x break else {
|
||||
x += 1
|
||||
|
||||
if error > 0 {
|
||||
y -= 1
|
||||
error += 4 * (@as(int, @intcast(x)) - @as(int, @intcast(y))) + 10
|
||||
error += 4 * (@intcast(x) - @intcast(y)) + 10
|
||||
} else {
|
||||
error += 4 * @intcast(x) + 6
|
||||
};
|
||||
*@inline(indexptr, surface, pos.x + x, pos.y + y) = color;
|
||||
*@inline(indexptr, surface, pos.x + y, pos.y + x) = color;
|
||||
*@inline(indexptr, surface, pos.x - x, pos.y + y) = color;
|
||||
*@inline(indexptr, surface, pos.x - y, pos.y + x) = color;
|
||||
*@inline(indexptr, surface, pos.x + x, pos.y - y) = color;
|
||||
*@inline(indexptr, surface, pos.x + y, pos.y - x) = color;
|
||||
*@inline(indexptr, surface, pos.x - x, pos.y - y) = color;
|
||||
*@inline(indexptr, surface, pos.x - y, pos.y - x) = color
|
||||
*indexptr(surface, pos.x + x, pos.y + y) = color;
|
||||
*indexptr(surface, pos.x + y, pos.y + x) = color;
|
||||
*indexptr(surface, pos.x - x, pos.y + y) = color;
|
||||
*indexptr(surface, pos.x - y, pos.y + x) = color;
|
||||
*indexptr(surface, pos.x + x, pos.y - y) = color;
|
||||
*indexptr(surface, pos.x + y, pos.y - x) = color;
|
||||
*indexptr(surface, pos.x - x, pos.y - y) = color;
|
||||
*indexptr(surface, pos.x - y, pos.y - x) = color
|
||||
}
|
||||
|
||||
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 {
|
||||
x := 0
|
||||
y := radius
|
||||
error := @as(int, 3) - @as(int, @intcast(2 * radius))
|
||||
@inline(put_hline, surface, pos.y - x, pos.x - radius, pos.x + radius, color);
|
||||
*@inline(indexptr, surface, pos.x, pos.y + radius) = color;
|
||||
*@inline(indexptr, surface, pos.x, pos.y - radius) = color
|
||||
error := @as(int, 3) - @intcast(2 * radius)
|
||||
put_hline(surface, pos.y - x, pos.x - radius, pos.x + radius, color);
|
||||
*indexptr(surface, pos.x, pos.y + radius) = color;
|
||||
*indexptr(surface, pos.x, pos.y - radius) = color
|
||||
|
||||
loop if y < x break else {
|
||||
x += 1
|
||||
|
||||
if error > 0 {
|
||||
@inline(put_hline, surface, pos.y + y, pos.x - x, pos.x + x, color)
|
||||
@inline(put_hline, surface, pos.y - y, pos.x - x, pos.x + x, color)
|
||||
put_hline(surface, pos.y + y, pos.x - x, pos.x + x, color)
|
||||
put_hline(surface, pos.y - y, pos.x - x, pos.x + x, color)
|
||||
y -= 1
|
||||
error += 4 * (@as(int, @intcast(x)) - @as(int, @intcast(y))) + 10
|
||||
error += 4 * (@intcast(x) - @intcast(y)) + 10
|
||||
} else {
|
||||
error += 4 * @intcast(x) + 6
|
||||
}
|
||||
@inline(put_hline, surface, pos.y + x, pos.x - y, pos.x + y, color)
|
||||
@inline(put_hline, surface, pos.y - x, pos.x - y, pos.x + y, color)
|
||||
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
|
||||
|
@ -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 {
|
||||
x := 0
|
||||
y := radius
|
||||
error := @as(int, 3) - @as(int, @intcast(2 * radius))
|
||||
@inline(memory.copy, Color, @inline(indexptr, source, source_pos.x - y, source_pos.y), @inline(indexptr, surface, pos.x - y, pos.y), 2 * y);
|
||||
*@inline(indexptr, surface, pos.x, pos.y + y) = *@inline(indexptr, source, source_pos.x, source_pos.y + y);
|
||||
*@inline(indexptr, surface, pos.x, pos.y - y) = *@inline(indexptr, source, source_pos.x, source_pos.y - y)
|
||||
error := @as(int, 3) - @intcast(2 * radius)
|
||||
memory.copy(Color, indexptr(source, source_pos.x - y, source_pos.y), indexptr(surface, pos.x - y, pos.y), 2 * y);
|
||||
*indexptr(surface, pos.x, pos.y + y) = *indexptr(source, source_pos.x, source_pos.y + y);
|
||||
*indexptr(surface, pos.x, pos.y - y) = *indexptr(source, source_pos.x, source_pos.y - y)
|
||||
|
||||
loop if y < x break else {
|
||||
x += 1
|
||||
|
||||
if error > 0 {
|
||||
@inline(memory.copy, Color, @inline(indexptr, source, source_pos.x - x, source_pos.y + y), @inline(indexptr, surface, pos.x - x, pos.y + y), 2 * x)
|
||||
@inline(memory.copy, Color, @inline(indexptr, source, source_pos.x - x, source_pos.y - y), @inline(indexptr, surface, pos.x - x, pos.y - y), 2 * x)
|
||||
memory.copy(Color, indexptr(source, source_pos.x - x, source_pos.y + y), indexptr(surface, pos.x - x, pos.y + y), 2 * x)
|
||||
memory.copy(Color, indexptr(source, source_pos.x - x, source_pos.y - y), indexptr(surface, pos.x - x, pos.y - y), 2 * x)
|
||||
y -= 1
|
||||
error += 4 * (@as(int, @intcast(x)) - @as(int, @intcast(y))) + 10
|
||||
error += 4 * (@intcast(x) - @intcast(y)) + 10
|
||||
} else {
|
||||
error += 4 * @intcast(x) + 6
|
||||
}
|
||||
@inline(memory.copy, Color, @inline(indexptr, source, source_pos.x - y, source_pos.y + x), @inline(indexptr, surface, pos.x - y, pos.y + x), 2 * y)
|
||||
@inline(memory.copy, Color, @inline(indexptr, source, source_pos.x - y, source_pos.y - x), @inline(indexptr, surface, pos.x - y, pos.y - x), 2 * y)
|
||||
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)
|
||||
}
|
||||
|
||||
return
|
||||
|
@ -364,7 +363,7 @@ put_text := fn(surface: Surface, font: Font, pos: Vec2(uint), color: Color, str:
|
|||
str += 1
|
||||
continue
|
||||
}
|
||||
glyph_data = @inline(get_glyph, font, *str)
|
||||
glyph_data = get_glyph(font, *str)
|
||||
} else {
|
||||
if *str < UNC_TABLE_SIZE {
|
||||
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
|
||||
}
|
||||
|
||||
dest := @inline(indexptr, surface, cursor.x, cursor.y)
|
||||
dest := indexptr(surface, cursor.x, cursor.y)
|
||||
rows := font.height
|
||||
|
||||
loop if rows == 0 break else {
|
||||
|
|
|
@ -74,16 +74,16 @@ font_from_psf2 := fn(psf: ^u8, unicode: bool): ?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
|
||||
}
|
||||
|
||||
UNC_TABLE_SIZE := 1 << 16
|
||||
$UNC_TABLE_SIZE := 1 << 16
|
||||
|
||||
init_unicode := fn(font: ^Font): void {
|
||||
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
|
||||
curr_glyph := @as(u16, 0)
|
||||
|
@ -121,8 +121,6 @@ init_unicode := fn(font: ^Font): void {
|
|||
next_byte := *table
|
||||
if (next_byte & 0xC0) != 0x80 {
|
||||
valid = false
|
||||
}
|
||||
if valid == false {
|
||||
break
|
||||
}
|
||||
unicode = unicode << 6 | next_byte & 0x3F
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
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))
|
||||
}
|
||||
|
||||
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))
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,14 @@ create := fn(msg: ^u8): uint {
|
|||
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 {
|
||||
return @eca(3, 0, BufferMsg.(3, msg, @inline(string.length, msg)), @sizeof(BufferMsg))
|
||||
}
|
|
@ -1,29 +1,14 @@
|
|||
abs := fn($Expr: type, x: Expr): Expr {
|
||||
mask := x >> @bitcast(@sizeof(Expr) - 1)
|
||||
return (x ^ mask) - mask
|
||||
$abs := fn($Expr: type, x: Expr): Expr {
|
||||
return (x ^ x >> @sizeof(Expr) - 1) - (x >> @sizeof(Expr) - 1)
|
||||
}
|
||||
min := fn($Expr: type, a: Expr, b: Expr): Expr {
|
||||
c := a - b
|
||||
return b + (c & c >> @bitcast(@sizeof(Expr) - 1))
|
||||
$min := fn($Expr: type, a: Expr, b: Expr): Expr {
|
||||
return b + (a - b & a - b >> @sizeof(Expr) - 1)
|
||||
}
|
||||
max := fn($Expr: type, a: Expr, b: Expr): Expr {
|
||||
c := a - b
|
||||
return a - (c & c >> @bitcast(@sizeof(Expr) - 1))
|
||||
$max := fn($Expr: type, a: Expr, b: Expr): Expr {
|
||||
return a - (a - b & a - b >> @sizeof(Expr) - 1)
|
||||
}
|
||||
signum := fn($Expr: type, x: Expr): int {
|
||||
if x > @as(Expr, @intcast(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
|
||||
$sign := fn($Expr: type, x: Expr): i8 {
|
||||
return @bitcast(x > 0) - @bitcast(x < 0)
|
||||
}
|
||||
|
||||
Vec2 := fn($Expr: type): type {
|
||||
|
|
|
@ -1,32 +1,26 @@
|
|||
PAGE_SIZE := 4096
|
||||
MAX_ALLOC := 0xFF
|
||||
MAX_FREE := 0xFF
|
||||
$PAGE_SIZE := 4096
|
||||
$MAX_ALLOC := 0xFF
|
||||
$MAX_FREE := 0xFF
|
||||
|
||||
is_uninit := fn($Expr: type, ptr: ^Expr): bool {
|
||||
i := 0
|
||||
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
|
||||
$uninit := fn($Expr: type): ?Expr {
|
||||
return null
|
||||
}
|
||||
|
||||
dangling := fn($Expr: type): ^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
|
||||
}
|
||||
|
||||
// ! will be replaced, don't get attached
|
||||
alloc := fn($Expr: type, num: uint): ^Expr {
|
||||
pages := @inline(calc_pages, Expr, num)
|
||||
pages := calc_pages(Expr, num)
|
||||
if pages <= MAX_ALLOC {
|
||||
return @bitcast(request_page(@intcast(pages)))
|
||||
}
|
||||
ptr := request_page(0xFF)
|
||||
ptr := request_page(MAX_ALLOC)
|
||||
remaining := pages - MAX_ALLOC
|
||||
loop if remaining < MAX_ALLOC break else {
|
||||
_ = request_page(@intcast(MAX_ALLOC))
|
||||
|
@ -37,46 +31,46 @@ alloc := fn($Expr: type, num: uint): ^Expr {
|
|||
}
|
||||
|
||||
// ! stub
|
||||
free := fn($Expr: type, ptr: ^Expr, num: uint, nullify: bool): void {
|
||||
$free := fn($Expr: type, ptr: ^Expr, num: uint, nullify: bool): void {
|
||||
return
|
||||
}
|
||||
|
||||
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))
|
||||
}
|
||||
|
||||
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))
|
||||
}
|
||||
|
||||
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))
|
||||
}
|
||||
|
||||
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))
|
||||
}
|
||||
|
||||
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))
|
||||
}
|
||||
|
||||
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))
|
||||
}
|
||||
|
||||
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))
|
||||
}
|
||||
|
||||
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))
|
||||
}
|
|
@ -3,5 +3,5 @@ any := fn($Expr: type): 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
|
||||
}
|
6
sysdata/libraries/stn/src/sleep.hb
Normal file
6
sysdata/libraries/stn/src/sleep.hb
Normal 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 {
|
||||
}
|
|
@ -4,118 +4,60 @@ length := fn(ptr: ^u8): uint {
|
|||
}
|
||||
|
||||
display_int := fn(num: int, p: ^u8, radix: uint): ^u8 {
|
||||
is_negative := num < 0
|
||||
if is_negative num = -num
|
||||
|
||||
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 {
|
||||
*ptr = 48
|
||||
ptr += 1
|
||||
} else {
|
||||
*ptr = 0x30;
|
||||
*(ptr + 1) = 0
|
||||
return p
|
||||
}
|
||||
|
||||
loop if num == 0 break else {
|
||||
digit := num % @bitcast(radix)
|
||||
if digit < 10 {
|
||||
*ptr = @intcast(digit) + 48
|
||||
} else {
|
||||
*ptr = @intcast(digit) + 55
|
||||
remainder := num % @bitcast(radix)
|
||||
num /= @bitcast(radix);
|
||||
*ptr = @intcast(remainder + 0x30)
|
||||
if remainder > 9 {
|
||||
*ptr = @intcast(remainder - 10 + 0x41)
|
||||
}
|
||||
ptr += 1
|
||||
num /= @bitcast(radix)
|
||||
}
|
||||
}
|
||||
|
||||
if negative {
|
||||
*ptr = 45
|
||||
if is_negative {
|
||||
*ptr = 0x2D
|
||||
ptr += 1
|
||||
};
|
||||
|
||||
*ptr = 0
|
||||
|
||||
@inline(reverse, digits_start)
|
||||
}
|
||||
// ! it gets broked when you do this ??
|
||||
// *ptr = 0
|
||||
|
||||
@inline(reverse, p)
|
||||
return p
|
||||
}
|
||||
|
||||
reverse := fn(s: ^u8): void {
|
||||
i := 0
|
||||
j := @inline(length, s) - 1
|
||||
j := s + @inline(length, s) - 1
|
||||
temp := @as(u8, 0)
|
||||
loop if i >= j break else {
|
||||
temp = *(s + i);
|
||||
*(s + i) = *(s + j);
|
||||
*(s + j) = temp
|
||||
i += 1
|
||||
loop if s < j {
|
||||
temp = *s;
|
||||
*s = *j;
|
||||
*j = temp
|
||||
s += 1
|
||||
j -= 1
|
||||
}
|
||||
return
|
||||
} else return
|
||||
}
|
||||
|
||||
equals := fn(lhs: ^u8, rhs: ^u8): bool {
|
||||
if lhs == rhs {
|
||||
return true
|
||||
}
|
||||
i := 0
|
||||
loop if *(lhs + i) != *(rhs + i) {
|
||||
loop if *lhs != *rhs {
|
||||
return false
|
||||
} else if *lhs == 0 {
|
||||
return true
|
||||
} 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
|
||||
}
|
|
@ -1,62 +1,63 @@
|
|||
.{math: .{Vec2}, buffer, log, memory} := @use("../../stn/src/lib.hb");
|
||||
.{Surface, new_surface} := @use("../../render/src/lib.hb");
|
||||
.{WindowWrapper, WindowID, WindowProps, WindowMessage, message, BUFFER} := @use("./lib.hb")
|
||||
.{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")
|
||||
|
||||
buffer_id := @as(?uint, null)
|
||||
// ! in the future this should be safely handled
|
||||
channel := Channel.(0, 0)
|
||||
|
||||
new_window := fn(props: WindowProps): ?WindowWrapper {
|
||||
if buffer_id == null {
|
||||
log.error("client: (request_new) buffer id is null. did you init the client?\0")
|
||||
return null
|
||||
}
|
||||
buf := memory.uninit(?WindowWrapper)
|
||||
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
|
||||
find_server := fn(): void {
|
||||
log.info("client: locating server\0")
|
||||
channel2 := await_channel()
|
||||
channel.server = channel2.server
|
||||
channel.client = channel2.client
|
||||
log.info("client: server located\0")
|
||||
}
|
||||
|
||||
update_window_props := fn(wrapper: WindowWrapper): ?WindowProps {
|
||||
log.error("todo: sunset_proto/src/client/update_window_props.hb\0")
|
||||
if buffer_id == null {
|
||||
log.error("client: (request_update_properties) buffer id is null. did you init the client?\0")
|
||||
new := fn(props: WindowProps): ?Window {
|
||||
send_header(message.syn, channel.server)
|
||||
response := await_message(Channel, channel.client)
|
||||
if response.header.kind != message.ack {
|
||||
return null
|
||||
}
|
||||
// TODO: buffer.write(WINDOWING_BUFFER, update properties) request
|
||||
log.info("client: recv ack\0")
|
||||
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 {
|
||||
if buffer_id == null {
|
||||
log.error("client: (request_shutdown) buffer id is null. did you init the client?\0")
|
||||
return null
|
||||
quit := fn(client: Window): void {
|
||||
send_header(message.quit, client.data.channel.server)
|
||||
}
|
||||
buf := memory.uninit(?u8)
|
||||
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 {
|
||||
}
|
||||
// loop until i write a better socket
|
||||
i := 0
|
||||
loop if i >= 1000 break else i += 1
|
||||
// had to do ?u8 here, ?bool didnt work
|
||||
if buf == null | @unwrap(buf) != 255 {
|
||||
return false
|
||||
} else {
|
||||
|
||||
connected := fn(client: Window): bool {
|
||||
return true
|
||||
}
|
||||
|
||||
shutdown_server := fn(client: Window): bool {
|
||||
return false
|
||||
}
|
||||
|
||||
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)
|
||||
update_props := fn(client: Window): bool {
|
||||
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
|
||||
}
|
||||
// ! 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
|
||||
}
|
|
@ -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")
|
||||
|
||||
$BUFFER := "sunset\0"
|
||||
$BUFFER_SERVER := "sunset_server\0"
|
||||
$BUFFER_CLIENT := "sunset_client\0"
|
||||
|
||||
Channel := packed struct {
|
||||
client: uint,
|
||||
server: uint,
|
||||
}
|
||||
|
||||
client := @use("./client.hb")
|
||||
server := @use("./server.hb")
|
||||
message := @use("./message.hb")
|
||||
permissions := @use("./permissions.hb")
|
||||
|
||||
WindowID := uint
|
||||
MessageKind := uint
|
||||
$send_message := fn($Expr: type, kind: MessageKind, msg: Expr, buffer_id: uint): void {
|
||||
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,
|
||||
id: WindowID,
|
||||
length: uint,
|
||||
data_ptr: ^u8,
|
||||
// need to replace this with a buffer id
|
||||
callback: ^u8,
|
||||
}
|
||||
|
||||
Message := fn($Expr: type): type {
|
||||
return packed struct {
|
||||
header: MessageHeader,
|
||||
body: Expr,
|
||||
}
|
||||
}
|
||||
|
||||
WindowProps := struct {
|
||||
position: Vec2(uint),
|
||||
dimensions: Vec2(uint),
|
||||
// ! replace with owned string type later
|
||||
title: ^u8,
|
||||
}
|
||||
|
||||
WindowWrapper := struct {
|
||||
id: WindowID,
|
||||
WindowData := struct {
|
||||
props: WindowProps,
|
||||
channel: Channel,
|
||||
permissions: uint,
|
||||
}
|
||||
|
||||
Window := struct {
|
||||
data: WindowData,
|
||||
surface: Surface,
|
||||
props: WindowProps,
|
||||
}
|
|
@ -1,4 +1,8 @@
|
|||
$new := 0
|
||||
$destroy := 1
|
||||
$update_props := 2
|
||||
$shutdown := 3
|
||||
// ! all values in this file are subject to change.
|
||||
$syn := 1
|
||||
$ack := 2
|
||||
$refused := 3
|
||||
$quit := 4
|
||||
$props := 5
|
||||
$shutdown := 6
|
||||
$frame_ready := 7
|
5
sysdata/libraries/sunset_proto/src/permissions.hb
Normal file
5
sysdata/libraries/sunset_proto/src/permissions.hb
Normal file
|
@ -0,0 +1,5 @@
|
|||
$none := 0b0
|
||||
$exclusive_framebuffer := 0b1
|
||||
$shutdown := 0b100
|
||||
|
||||
$default := none
|
|
@ -1,34 +1,135 @@
|
|||
.{math, log, string, random, buffer, memory} := @use("../../stn/src/lib.hb");
|
||||
.{Surface, new_surface} := @use("../../render/src/lib.hb");
|
||||
.{WindowWrapper, WindowID, WindowProps, WindowMessage, BUFFER} := @use("./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");
|
||||
.{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}
|
||||
|
||||
server := @as(?WindowServer, null)
|
||||
|
||||
new_window_id := fn(): WindowID {
|
||||
return random.any(uint)
|
||||
WindowServer := struct {
|
||||
window_count: uint,
|
||||
channel: Channel,
|
||||
// ! replace this with a collection when we get an allocator
|
||||
windows: [?Window; 10],
|
||||
font: text.Font,
|
||||
}
|
||||
|
||||
init := fn(): bool {
|
||||
log.info("server: starting server\0")
|
||||
server = .(0, buffer.create(BUFFER))
|
||||
// ! in the future this should be safely handled
|
||||
server := @as(WindowServer, idk)
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
recieve := fn(): ?WindowMessage {
|
||||
if server == null {
|
||||
log.error("server: (request_new) server is null. did you init the client?\0")
|
||||
return null
|
||||
}
|
||||
buf := memory.uninit(WindowMessage)
|
||||
buffer.recv(WindowMessage, @unwrap(server).buffer_id, @bitcast(&buf))
|
||||
if memory.is_uninit(WindowMessage, &buf) {
|
||||
return null
|
||||
}
|
||||
return buf
|
||||
$DECO_WIDTH := 2
|
||||
$DECO_HEIGHT_TOP := 20
|
||||
$DECO_HEIGHT_BOTTOM := 1
|
||||
$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,
|
||||
)
|
||||
}
|
||||
|
||||
should_shutdown := fn(): bool {
|
||||
return false
|
||||
// ! compositor code. this currently disallows tearing.
|
||||
|
||||
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
|
||||
}
|
||||
}
|
|
@ -56,23 +56,13 @@ main := fn(): int {
|
|||
loop {
|
||||
// Clear the screen
|
||||
render.clear(screen, render.black)
|
||||
|
||||
render.put_surface(screen, wallpaper, .(0, 0), false)
|
||||
|
||||
// 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 {
|
||||
// Scroll bar :ThumbsUp:
|
||||
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)
|
||||
}
|
||||
|
||||
{
|
||||
// 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)
|
||||
render_label_to_surface(screen, text_label, font, pos)
|
||||
|
@ -91,12 +87,20 @@ main := fn(): int {
|
|||
// Screen border
|
||||
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()
|
||||
//
|
||||
|
||||
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 = change_x << 8
|
||||
|
@ -133,13 +137,9 @@ main := fn(): int {
|
|||
}
|
||||
}
|
||||
|
||||
// render mouse
|
||||
lum := render.indexptr(screen, mouse_x, mouse_y)
|
||||
if lum.r / 3 + lum.g / 3 + lum.b / 3 < 128 {
|
||||
render.put_filled_rect(screen, .(mouse_x, mouse_y), .(20, 20), render.black)
|
||||
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
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
||||
memory.outb(96, byte)
|
||||
|
@ -6,23 +10,31 @@ send_byte := fn(byte: u8): u8 {
|
|||
}
|
||||
|
||||
main := fn(): int {
|
||||
buf := buffer.create("XKeyboard\0")
|
||||
buf := buffer.create("PS/2 Keyboard\0")
|
||||
_ = send_byte(238)
|
||||
log.info("PS/2 Driver Loaded\0")
|
||||
|
||||
if send_byte(238) == 238 {
|
||||
log.info("PS/2 Keyboard Echoed\0")
|
||||
}
|
||||
|
||||
if send_byte(244) == 250 {
|
||||
log.info("Enabled scanning\0")
|
||||
}
|
||||
|
||||
prev_input := 250
|
||||
loop {
|
||||
loop if (memory.inb(0x64) & 0x20) == 0x20 break
|
||||
|
||||
input := memory.inb(96)
|
||||
|
||||
if input == prev_input {
|
||||
continue
|
||||
}
|
||||
prev_input = input
|
||||
buffer.write(u8, &input, buf)
|
||||
kevent := KeyEvent.(false, true, input)
|
||||
|
||||
buffer.write(KeyEvent, buf, &kevent)
|
||||
}
|
||||
return 0
|
||||
}
|
|
@ -145,7 +145,7 @@ main := fn(): int {
|
|||
event.x_change = x_change
|
||||
event.y_change = y_change
|
||||
|
||||
buffer.write(MouseEvent, &event, mouse_buffer)
|
||||
buffer.write(MouseEvent, mouse_buffer, &event)
|
||||
}
|
||||
|
||||
return 0
|
||||
|
|
|
@ -10,12 +10,12 @@ example := fn(): void {
|
|||
color := render.light_cyan
|
||||
n := @as(u8, 1)
|
||||
loop {
|
||||
// ! dead code elimination bug
|
||||
render.clear(screen, color)
|
||||
render.sync(screen)
|
||||
if (color.b & 255) == 255 | (color.b & 255) == 0 {
|
||||
if color.b == 255 | color.b == 0 {
|
||||
n = -n
|
||||
}
|
||||
color.b += n
|
||||
}
|
||||
return
|
||||
}
|
|
@ -46,7 +46,7 @@ example := fn(): void {
|
|||
|
||||
bottom := buf + msg_len
|
||||
|
||||
@inline(memory.copy, u8, msg, buf, msg_len)
|
||||
memory.copy(u8, msg, buf, msg_len)
|
||||
cursor := bottom
|
||||
|
||||
draw_window(window, font, buf, cursor)
|
||||
|
|
|
@ -1 +1 @@
|
|||
.{example: main} := @use("./examples/orbit.hb")
|
||||
.{example: main} := @use("./examples/text.hb")
|
|
@ -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")
|
||||
render := @use("../../../libraries/render/src/lib.hb")
|
||||
|
||||
bmp := @embed("../../../assets/mini.bmp")
|
||||
|
||||
main := fn(): void {
|
||||
sunset.client.init()
|
||||
log.info("client: request new window\0")
|
||||
window := sunset.client.new_window(.(.(100, 100), .(150, 150), "Hello, World!\0"))
|
||||
if window == null {
|
||||
log.error("Could not create window\0")
|
||||
sunset.client.find_server()
|
||||
|
||||
image := render.image.bmp.from(@bitcast(&bmp))
|
||||
if image == null {
|
||||
log.error("got no image\0")
|
||||
return
|
||||
}
|
||||
log.info("client: window created. title:\0")
|
||||
log.info(window.props.title)
|
||||
window.props.position = .(500, 500)
|
||||
props := @unwrap(sunset.client.update_window_props(window))
|
||||
if props.position.x != window.props.position.x {
|
||||
log.error("client: we did not update props\0")
|
||||
|
||||
window := sunset.client.new(.(.(100, 100), .(200, 200), "Hello,\0"))
|
||||
|
||||
if window == null {
|
||||
log.error("got no window\0")
|
||||
return
|
||||
}
|
||||
log.info("client: sending shutdown request\0")
|
||||
shutdown := sunset.client.request_shutdown()
|
||||
if shutdown == null {
|
||||
log.error("client: didnt shutdown the server\0")
|
||||
x := 0
|
||||
loop {
|
||||
render.clear(window.surface, render.black)
|
||||
render.put_surface(window.surface, image, .(image.width + x % window.data.props.dimensions.x, 20), false)
|
||||
_ = sunset.client.send_frame(window)
|
||||
x += 1
|
||||
}
|
||||
}
|
11
sysdata/programs/sunset_client_2/meta.toml
Normal file
11
sysdata/programs/sunset_client_2/meta.toml
Normal 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"
|
29
sysdata/programs/sunset_client_2/src/main.hb
Normal file
29
sysdata/programs/sunset_client_2/src/main.hb
Normal 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
|
||||
}
|
||||
}
|
|
@ -1,36 +1,98 @@
|
|||
.{log} := @use("../../../libraries/stn/src/lib.hb")
|
||||
render := @use("../../../libraries/render/src/lib.hb");
|
||||
.{server, message, WindowWrapper, WindowProps} := @use("../../../libraries/sunset_proto/src/lib.hb")
|
||||
sunset := @use("../../../libraries/sunset_proto/src/lib.hb")
|
||||
render := @use("../../../libraries/render/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")
|
||||
img := @embed("../../../assets/wallpaper.qoi")
|
||||
|
||||
main := fn(): void {
|
||||
screen := render.init(false)
|
||||
font := render.text.font_from_psf2(@bitcast(&psf), false)
|
||||
if font == null {
|
||||
return
|
||||
}
|
||||
if server.init() == false {
|
||||
log.error("Failed to create server\0")
|
||||
return
|
||||
}
|
||||
loop if server.should_shutdown() break else {
|
||||
recv := server.recieve()
|
||||
if recv == null {
|
||||
continue
|
||||
} else if recv.kind == message.new {
|
||||
props := *@as(^WindowProps, @bitcast(recv.data_ptr));
|
||||
*@as(^?WindowWrapper, @bitcast(recv.callback)) = WindowWrapper.(0, props)
|
||||
render.put_rect(screen, props.position, props.dimensions, render.white)
|
||||
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)
|
||||
log.info("server: made a new window\0")
|
||||
} else if recv.kind == message.shutdown {
|
||||
*@as(^?u8, @bitcast(recv.callback)) = 255
|
||||
break
|
||||
}
|
||||
main := fn(): int {
|
||||
sunset.server.start()
|
||||
|
||||
screen := render.init(true)
|
||||
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
|
||||
}
|
||||
|
||||
render.put_text(screen, font, .(0, 0), render.white, "Shutdown triggered\0")
|
||||
log.info("Server shutdown\0")
|
||||
mouse_x := 100
|
||||
mouse_y := 100
|
||||
|
||||
text_label := new_label("Hi\0")
|
||||
|
||||
loop {
|
||||
mouse_event := intouch.recieve_mouse_event()
|
||||
if mouse_event != null {
|
||||
change_x := @as(i16, mouse_event.x_change)
|
||||
change_x = change_x << 8
|
||||
change_x = change_x >> 8
|
||||
|
||||
mouse_x += change_x
|
||||
if mouse_x < 0 {
|
||||
mouse_x = 0
|
||||
}
|
||||
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)
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
|
@ -28,8 +28,8 @@ resolution = "1024x768x24"
|
|||
# [boot.limine.ableos.modules.horizon]
|
||||
# path = "boot:///horizon.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"
|
||||
|
|
4
todo.md
4
todo.md
|
@ -19,12 +19,14 @@
|
|||
@morshy
|
||||
Simple Userland Allocator
|
||||
|
||||
@funky
|
||||
Kernel Testing Framework (A rust framework for testing the kernel)
|
||||
|
||||
@unassigned
|
||||
FileIO (Fat32)
|
||||
DiskIO (Undecided Disk type)
|
||||
Proper Memory Protection
|
||||
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)
|
||||
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)
|
||||
|
|
Loading…
Reference in a new issue