From 78f050e20cb66f02d7455d594daf54e9ab0c677f Mon Sep 17 00:00:00 2001 From: Kevin Date: Sat, 30 Mar 2024 17:36:54 -0400 Subject: [PATCH] feat: put_pixel dark example --- Cargo.toml | 4 ++ examples/dark.rs | 118 +++++++++++++++++++++++++++++++++++++++++ src/modules/windows.rs | 9 ++++ src/sys.rs | 4 ++ src/syscalls.S | 9 ++++ 5 files changed, 144 insertions(+) create mode 100644 examples/dark.rs diff --git a/Cargo.toml b/Cargo.toml index 4a39710..7c11c39 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,6 +14,10 @@ path = "examples/hwa.rs" name = "con" path = "examples/con.rs" +[[example]] +name = "dark" +path = "examples/dark.rs" + [profile.release] opt-level = "z" lto = "thin" diff --git a/examples/dark.rs b/examples/dark.rs new file mode 100644 index 0000000..6b75c8f --- /dev/null +++ b/examples/dark.rs @@ -0,0 +1,118 @@ +#![no_std] +#![no_main] + +use cstr_core::{cstr, CStr}; + +use kos::{ + graphics::{display_message, Color, Dot, Size}, + input::fetch_key, + threads::{exit, fetch_event, Event}, + windows::{ + define_button, define_window, end_window_draw, get_button_id, invert_pixel, + start_window_draw, WindowKind, WindowParams, CLOSE_BUTTON, + }, +}; + +const HEADER: &CStr = cstr!("Dark Mode Demo"); +const TEXT: [&CStr; 6] = [ + cstr!("Lorem ipsum dolor sit amet,"), + cstr!("semper et rutrum placerat,"), + cstr!("Integer sed diam commodo quam varius"), + cstr!("Sed finibus urna sit amet felis"), + cstr!("vestibulum elementum. Maecenas at feugiat lacus"), + cstr!("tristique et sit amet tortor."), +]; +const BTN: u32 = 42; +const WINDOW_SIZE: Size = Size { + width: 400, + height: 400, +}; + +extern crate alloc; + +fn draw_window(invert: bool) { + start_window_draw(); + + define_window( + Dot { x: 50, y: 50 }, + WINDOW_SIZE, + WindowParams { + color: Color::rgb(0xff, 0xff, 0xff), + kind: WindowKind::FixedThemed, + title: Some(HEADER), + }, + ); + + display_message(Dot { x: 10, y: 10 }, Color::rgb(0, 0, 0), TEXT[0], None); + display_message(Dot { x: 10, y: 50 }, Color::rgb(0, 0, 0), TEXT[1], None); + display_message(Dot { x: 10, y: 90 }, Color::rgb(0, 0, 0), TEXT[2], None); + display_message(Dot { x: 10, y: 130 }, Color::rgb(0, 0, 0), TEXT[3], None); + display_message(Dot { x: 10, y: 170 }, Color::rgb(0, 0, 0), TEXT[4], None); + display_message(Dot { x: 10, y: 210 }, Color::rgb(0, 0, 0), TEXT[5], None); + + define_button( + Dot { x: 10, y: 300 }, + Size { + width: 100, + height: 30, + }, + BTN, + true, + true, + Some(Color::rgb(147, 112, 219)), + ); + + display_message( + Dot { x: 20, y: 310 }, + Color::rgb(255, 255, 255), + if invert { + cstr!("Light mode") + } else { + cstr!("Dark mode") + }, + None, + ); + + if invert { + for x in 0..WINDOW_SIZE.width { + for y in 0..WINDOW_SIZE.height { + invert_pixel(Dot { x, y }) + } + } + } + + end_window_draw(); + + return; +} + +fn button_handler(invert: &mut bool) { + let btn_id = get_button_id(); + + if btn_id.is_some() { + match btn_id.unwrap() { + CLOSE_BUTTON => exit(), + BTN => { + *invert = !*invert; + draw_window(*invert); + } + _ => {} + } + } +} + +#[no_mangle] +fn kol_main() { + let mut invert = false; + + while let Some(ev) = + fetch_event((Event::Redraw as u32) | (Event::KeyPress as u32) | (Event::BtnPress as u32)) + { + match ev { + Event::Redraw => draw_window(invert), + Event::KeyPress => drop(fetch_key()), + Event::BtnPress => button_handler(&mut invert), + _ => break, + } + } +} diff --git a/src/modules/windows.rs b/src/modules/windows.rs index d6e5785..5c8ff7a 100644 --- a/src/modules/windows.rs +++ b/src/modules/windows.rs @@ -39,6 +39,15 @@ pub fn define_window(start: Dot, size: Size, params: WindowParams<'_>) { } } +pub fn put_pixel(pos: Dot, color: Option) { + let color: u32 = color.unwrap_or(Color::rgb(255, 255, 255)).as_rgb_val(); + unsafe { sys::put_pixel(pos.x, pos.y, color) } +} + +pub fn invert_pixel(pos: Dot) { + unsafe { sys::put_pixel(pos.x, pos.y, 1 << 24) } +} + pub fn define_button( start: Dot, size: Size, diff --git a/src/sys.rs b/src/sys.rs index c0bd7e1..41188e8 100644 --- a/src/sys.rs +++ b/src/sys.rs @@ -8,6 +8,10 @@ extern "C" { #[link_name = "_define_window"] pub fn define_window(ebx: u32, ecx: u32, edx: u32, esi: u32, edi: u32); + // 1 + #[link_name = "_put_pixel"] + pub fn put_pixel(ebx: u32, ecx: u32, edx: u32); + // 2 #[link_name = "_pressed_key"] pub fn pressed_key() -> u32; diff --git a/src/syscalls.S b/src/syscalls.S index b314bf1..85570eb 100644 --- a/src/syscalls.S +++ b/src/syscalls.S @@ -7,6 +7,7 @@ section '.text' public _start_window_draw public _end_window_draw public _define_window + public _put_pixel public _display_message public _wait_event public _pressed_key @@ -50,6 +51,14 @@ _define_window: pop edi ret +_put_pixel: + mov eax, SF_PUT_PIXEL + mov ebx, dword [esp + 4 * 1] + mov ecx, dword [esp + 4 * 2] + mov edx, dword [esp + 4 * 3] + int 0x40 + ret + _display_message: push esi edi mov eax, SF_DRAW_TEXT