diff --git a/Cargo.lock b/Cargo.lock index 04446de..e5d52b0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -13,6 +13,7 @@ dependencies = [ "conquer-once", "crossbeam-channel", "crossbeam-queue", + "embedded-time", "futures-util", "hashbrown", "lazy_static", @@ -169,6 +170,15 @@ dependencies = [ "cfg-if 0.1.10", ] +[[package]] +name = "embedded-time" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7a4b4d10ac48d08bfe3db7688c402baadb244721f30a77ce360bd24c3dffe58" +dependencies = [ + "num", +] + [[package]] name = "futures-core" version = "0.3.28" @@ -248,6 +258,69 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" +[[package]] +name = "num" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b7a8e9be5e039e2ff869df49155f1c06bd01ade2117ec783e56ab0932b67a8f" +dependencies = [ + "num-complex", + "num-integer", + "num-iter", + "num-rational", + "num-traits", +] + +[[package]] +name = "num-complex" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "747d632c0c558b87dbabbe6a82f3b4ae03720d0646ac5b7b4dae89394be5f2c5" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-integer" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12ac428b1cb17fce6f731001d307d351ec70a6d202fc2e60f7d4c5e42d8f4f07" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" +dependencies = [ + "autocfg", +] + [[package]] name = "once_cell" version = "1.18.0" diff --git a/Cargo.toml b/Cargo.toml index c3c88cf..8662423 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,6 +31,7 @@ cmos-rtc = "0.1.2" libm = "0.2.7" log = "0.4.20" uchan = { version = "0.1.4", default-features = false } +embedded-time = "0.12.1" [dependencies.lazy_static] version = "1.0" diff --git a/src/system/kernel/tasks/keyboard.rs b/src/system/kernel/tasks/keyboard.rs index a0d36a2..69ae9c2 100644 --- a/src/system/kernel/tasks/keyboard.rs +++ b/src/system/kernel/tasks/keyboard.rs @@ -70,6 +70,29 @@ impl KeyboardHandler { } } + pub fn try_keystroke(&mut self) -> Option { + if let Some(scancode) = self.scancodes.try_next() { + if let Ok(Some(key_event)) = self.keyboard.add_byte(scancode) { + if let Some(key) = self.keyboard.process_keyevent(key_event) { + match key { + DecodedKey::Unicode(character) => { + if character == b'\x08' as char { // checks if the character is a backspace + interrupts::without_interrupts(|| { + RENDERER.lock().backspace(); // runs the backspace function of the vga buffer to remove the last character + }); + return None; + } else { + return Some(character); + } + }, + DecodedKey::RawKey(key) => { print!("{:?}", key) }, + } + } + } + }; + None + } + pub async fn get_string(&mut self) -> String { let mut val = String::new(); @@ -116,6 +139,15 @@ impl ScanCodeStream { .expect("ScanCodeStream::new has already been called once"); ScanCodeStream { _private: () } } + + pub fn try_next(&mut self) -> Option { + let queue = SCANCODE_QUEUE.try_get().expect("not initialised"); + if let Ok(c) = queue.pop() { + return Some(c); + } else { + return None; + } + } } impl Stream for ScanCodeStream { diff --git a/src/system/std/io.rs b/src/system/std/io.rs index 2f4cab8..4f5a335 100644 --- a/src/system/std/io.rs +++ b/src/system/std/io.rs @@ -22,6 +22,11 @@ impl Stdin { let chr = KEYBOARD.lock().get_keystroke().await; chr } + + pub fn try_keystroke() -> Option { + let chr = KEYBOARD.lock().try_keystroke(); + chr + } } pub struct Screen {} diff --git a/src/system/std/mod.rs b/src/system/std/mod.rs index 79b68bc..ddeeb62 100644 --- a/src/system/std/mod.rs +++ b/src/system/std/mod.rs @@ -4,6 +4,7 @@ pub mod application; pub mod tasks; pub mod os; pub mod frame; +pub mod time; // this is where the standard library for the operating system will be defined diff --git a/src/system/std/time.rs b/src/system/std/time.rs new file mode 100644 index 0000000..4d7274d --- /dev/null +++ b/src/system/std/time.rs @@ -0,0 +1,28 @@ +use core::time::Duration; +use embedded_time::{Clock, Timer}; +use cmos_rtc::{ReadRTC, Time}; +use crate::println; +use super::super::kernel::interrupts::GLOBALTIMER; +use x86_64::instructions::interrupts; +pub fn wait(seconds: i64) { + let mut start = 0; + interrupts::without_interrupts(||{ + start = GLOBALTIMER.lock().val; + }); + + loop { + let mut new = 0; + interrupts::without_interrupts(||{ + new = GLOBALTIMER.lock().val; + }); + if new + seconds > start { + return + } + }; +} + +pub fn timer() { + interrupts::without_interrupts(||{ + println!("{}", GLOBALTIMER.lock().val); + }); +} \ No newline at end of file diff --git a/src/user/bin/mod.rs b/src/user/bin/mod.rs index f90700c..88ce175 100644 --- a/src/user/bin/mod.rs +++ b/src/user/bin/mod.rs @@ -6,5 +6,5 @@ pub mod shell; //pub mod shellrewrite; pub mod tasks; mod gigachad_detector; -mod shellrewrite; +//mod shellrewrite; mod snake; diff --git a/src/user/bin/shell.rs b/src/user/bin/shell.rs index a1e1763..0886c79 100644 --- a/src/user/bin/shell.rs +++ b/src/user/bin/shell.rs @@ -132,6 +132,10 @@ async fn exec() -> Result<(), Error> { "gigachad?" => { let mut gigachad_detector = GigachadDetector::new(); gigachad_detector.run(args).await?; + } + "time" => { + use crate::std::time::timer; + timer(); } "test_features" => { use crate::std::random::Random; diff --git a/src/user/bin/snake.rs b/src/user/bin/snake.rs index 6d0b888..b23683f 100644 --- a/src/user/bin/snake.rs +++ b/src/user/bin/snake.rs @@ -1,7 +1,8 @@ use alloc::string::String; use alloc::{format, vec, vec::Vec, boxed::Box}; use async_trait::async_trait; -use crate::std::io::{Color, Screen}; +use crate::std::io::{Color, Screen, Stdin}; +use crate::std::time; use crate::kernel::tasks::keyboard::KEYBOARD; use crossbeam_queue::SegQueue; use crate::kernel::render::{ColorCode, ScreenChar}; @@ -19,6 +20,7 @@ pub struct Game { snake: SegQueue, head: Point, poi: Point, + mv: char, score: u8 } @@ -29,22 +31,34 @@ impl Application for Game { snake: SegQueue::new(), head: Point { x: 5, y: 5 }, poi: Point { x: 0, y: 0 }, + mv: ' ', score: 0 } } async fn run(&mut self, _: Vec) -> Result<(), Error> { Screen::application_mode(); + let clone = self.clone_snake(); + self.render(clone).map_err(|_| Error::ApplicationError(String::from("failed to render game screen")))?; - (0..=2).for_each(|x| { + + (5..=7).for_each(|x| { self.snake.push(Point { x, y: 5 }); }); - self.head = Point { x: 2, y: 5 }; + self.head = Point { x: 7, y: 5 }; self.new_poi(); 'gameloop: loop { - let chr = KEYBOARD.lock().get_keystroke().await; - match chr { + + time::wait(20); + + // if let Some(c) = Stdin::try_keystroke() { + // self.mv = c; + // } + + self.mv = Stdin::keystroke().await; + + match self.mv { 'w' => self.head.y -= 1, 'a' => self.head.x -= 1, 's' => self.head.y += 1, @@ -52,6 +66,7 @@ impl Application for Game { 'x' => break, _ => continue, } + self.snake.push(Point { x: self.head.x, y: self.head.y }); // new head added if self.head == self.poi {