.{memory, buffer, log, string, math} := @use("../../../libraries/stn/src/lib.hb") Vec2 := math.Vec2 intouch := @use("../../../libraries/intouch/src/lib.hb"); .{MouseEvent} := intouch.events i9 := packed struct {sign: bool, value: u8} Button := struct {id: u8} $LeftButton := Button.(1) $RightButton := Button.(2) $MiddleButton := Button.(4) $Button4 := Button.(8) $Button5 := Button.(16) send_byte := fn(target: u8, data: u8): void { loop if (memory.inb(0x64) & 2) == 0 break memory.outb(target, data) } reset_mouse := fn(): void { @inline(send_byte, 0x64, 0xD4) @inline(send_byte, 0x60, 0xFF) loop if memory.inb(0x60) == 0xAA { log.info("Self check passed.\0") return } } send_command_byte := fn(byte: u8): void { @inline(send_byte, 0x64, 0xD4) @inline(send_byte, 0x60, byte) loop if memory.inb(0x60) == 0xFA { return } } set_defaults := fn(): void @inline(send_command_byte, 0xF6) disable_streaming := fn(): void @inline(send_command_byte, 0xF5) enable_streaming := fn(): void @inline(send_command_byte, 0xF4) set_remote_mode := fn(): void @inline(send_command_byte, 0xF0) set_warp_mode := fn(): void @inline(send_command_byte, 0xEE) reset_warp_mode := fn(): void @inline(send_command_byte, 0xEC) set_stream_mode := fn(): void @inline(send_command_byte, 0xEA) set_non_linear_scaling := fn(): void @inline(send_command_byte, 0xE7) set_linear_scaling := fn(): void @inline(send_command_byte, 0xE6) resend_packet := fn(): void @inline(send_command_byte, 0xFE) SampleRate := struct {value: u8} $sr10 := SampleRate.(10) $sr20 := SampleRate.(20) $sr40 := SampleRate.(40) $sr60 := SampleRate.(60) $sr80 := SampleRate.(80) $sr100 := SampleRate.(100) $sr200 := SampleRate.(200) set_sample_rate := fn(sample_rate: SampleRate): void { @inline(send_command_byte, 0xE6) @inline(send_command_byte, sample_rate.value) } Resolution := struct {value: u8} $res_1count_per_mm := Resolution.(0) $res_2count_per_mm := Resolution.(1) $res_4count_per_mm := Resolution.(2) $res_8count_per_mm := Resolution.(3) set_resolution := fn(resolution: Resolution): void { @inline(send_command_byte, 0xE6) @inline(send_command_byte, resolution.value) } set_up_mouse := fn(): void { @inline(reset_mouse) @inline(set_resolution, res_8count_per_mm) @inline(enable_streaming) } button_states := @as(u8, 0) main := fn(): int { mouse_buffer := buffer.create("PS/2 Mouse\0") format_page := memory.alloc(u8, 1024) send_byte(0x64, 0xA8) log.info("Aux mouse device enabled.\0") set_up_mouse() set_resolution(res_8count_per_mm) x := @as(u8, 0) y := @as(u8, 0) loop { loop if (memory.inb(0x64) & 0x20) == 0x20 break status := memory.inb(0x60) if status == 0xAA { loop if memory.inb(0x60) == 0 break log.info("Mouse plugged in!\0") set_up_mouse() continue } event := MouseEvent.(0, 0, false, false, false) changes := button_states ^ status & 7 if (changes & LeftButton.id) != 0 | (status & LeftButton.id) != 0 { event.left = true } else { event.left = false } if (changes & MiddleButton.id) != 0 | (status & MiddleButton.id) != 0 { event.middle = true } else { event.middle = false } if (changes & RightButton.id) != 0 | (status & RightButton.id) != 0 { event.right = true } else { event.right = false } button_states ^= changes dx := i9.(false, 0) dy := i9.(false, 0) dx.value = memory.inb(0x60) dx.sign = (status & 0x10) > 0 dy.value = memory.inb(0x60) dy.sign = (status & 0x20) != 0 y_change := @as(i8, @bitcast(dy.value)) x_change := @as(i8, @bitcast(dx.value)) event.x_change = x_change event.y_change = y_change buffer.write(MouseEvent, mouse_buffer, &event) } return 0 }