several fixes and changes

This commit is contained in:
FantasyPvP
2023-11-29 23:45:40 +00:00
parent d89a30d390
commit 7ae2308a83
10 changed files with 215 additions and 68 deletions
Generated
+1
View File
@@ -20,6 +20,7 @@ dependencies = [
"libm", "libm",
"linked_list_allocator", "linked_list_allocator",
"log", "log",
"num-traits",
"pc-keyboard", "pc-keyboard",
"pic8259", "pic8259",
"rand", "rand",
+1
View File
@@ -32,6 +32,7 @@ log = "0.4.20"
uchan = { version = "0.1.4", default-features = false } uchan = { version = "0.1.4", default-features = false }
embedded-time = "0.12.1" embedded-time = "0.12.1"
vga = "0.2.9" vga = "0.2.9"
num-traits = { version = "0.2.16", default-features = false }
[dependencies.lazy_static] [dependencies.lazy_static]
version = "1.0" version = "1.0"
+1 -1
View File
@@ -1,2 +1,2 @@
cargo bootimage --release cargo bootimage --release
sudo dd if=target/x86_64-CrystalOS/release/bootimage-CrystalOS.bin of=/dev/sdc sudo dd if=target/x86_64-CrystalOS/release/bootimage-CrystalOS.bin of=/dev/sdb
+140 -4
View File
@@ -1,23 +1,159 @@
use crate::system::std::application::Application; use crate::system::std::application::Application;
use async_trait::async_trait; use async_trait::async_trait;
use alloc::boxed::Box; use alloc::boxed::Box;
use alloc::string::String; use alloc::format;
use alloc::string::{String, ToString};
use alloc::vec::Vec; use alloc::vec::Vec;
use core::any::Any;
use crate::{serial_println, std};
use crate::std::application::Error; use crate::std::application::Error;
use crate::std::application::Error::ApplicationError;
use crate::std::frame::{Position, Dimensions, RenderError, Frame, ColouredChar};
use crate::std::io::{Color, ColorCode, KeyStroke, Screen, Stdin};
use crate::std::random::Random;
use crate::user::lib::libgui::cg_core::{CgComponent, Widget};
use crate::user::lib::libgui::cg_widgets::{CgContainer, CgIndicatorWidget};
#[derive(Clone)]
pub struct Player { pub struct Player {
pub health: u32, pub health: u32,
pub score: u32 pub position: Position,
} }
impl Player { impl Player {
pub fn new() -> Player { pub fn new() -> Player {
Player { Player {
health: 5, health: 5,
score: 0 position: Position::new(10, 12)
} }
} }
} }
#[derive(Clone)]
pub struct Game { pub struct Game {
pub player: Player pub player: Player,
pub enemies: Vec<Enemy>,
pub score: u32,
} }
#[async_trait]
impl Application for Game {
fn new() -> Self {
Self {
player: Player::new(),
enemies: Vec::new(),
score: 0
}
}
async fn run(&mut self, args: Vec<String>) -> Result<(), Error> {
let mut spawn_timer: i32 = 0;
Screen::Application.set_mode().unwrap();
let mut container_data = CgContainer::new(
Position::new(0, 0),
Dimensions::new(80, 25),
true,
);
let self_ref = Widget::insert(self.clone());
container_data.insert("app", self_ref);
let self_ref = container_data.fetch("app").unwrap();
loop {
std::time::wait(0.1);
spawn_timer += 1;
if spawn_timer >= 8 {
spawn_timer = 0;
self.enemies.push(Enemy::new(Random::int(1, 21)));
}
self.enemies.retain(|e| {if e.position.x <= 0 {self.score += 1; false } else { true }});
self.enemies.iter_mut().for_each(|e| e.position.x -= 1);
self.enemies.iter().for_each(|e| { if e.position.x == self.player.position.x && e.position.y == self.player.position.y { self.player.health -= 1; } });
if self.player.health == 0 {
break;
}
if let Some(input_key) = Stdin::try_keystroke() {
match input_key {
KeyStroke::Char('q') => {
break;
}
KeyStroke::Char('w') => self.player.position.y -= 1,
KeyStroke::Char('s') => self.player.position.y += 1,
KeyStroke::Char('a') => self.player.position.x -= 1,
KeyStroke::Char('d') => self.player.position.x += 1,
_ => (),
}
}
self_ref.update(self.clone());
if let Ok(frame) = container_data.render() {
frame.write_to_screen().unwrap();
}
}
let mut frame = Frame::new(Dimensions::new(0, 0), Dimensions::new(80, 25)).map_err(|_| ApplicationError("idk".to_string()))?;
let msg = format!("your score was: {}", self.score);
msg.chars().enumerate().for_each(|(i, c)| {
serial_println!("{}", (80 - msg.len()) / 2 + i);
frame[12][(80 - msg.len()) / 2 + i] = ColouredChar {
character: c,
colour: ColorCode::new(Color::Cyan, Color::Black),
}
});
frame.write_to_screen().unwrap();
while let KeyStroke::Char(c) = Stdin::keystroke().await {
if c == 'q' {
break;
}
}
Screen::Terminal.set_mode().unwrap();
Ok(())
}
}
impl CgComponent for Game {
fn render(&self) -> Result<Frame, RenderError> {
let mut frame = Frame::new(Dimensions::new(1, 1), Dimensions::new(78, 23))?;
let pos = self.player.position;
frame[pos.y][pos.x] = ColouredChar {
character: '@',
colour: ColorCode::new(Color::Cyan, Color::Black),
};
for i in self.enemies.iter().map(|enemy| enemy.position).collect::<Vec<Position>>() {
frame[i.y][i.x] = ColouredChar {
character: '*',
colour: ColorCode::new(Color::Red, Color::Black),
}
}
Ok(frame)
}
fn as_any(&self) -> &dyn Any {
self
}
}
#[derive(Clone)]
pub struct Enemy {
pub position: Position
}
impl Enemy {
pub fn new(y: usize) -> Enemy {
Enemy {
position: Position::new(75, y)
}
}
}
+1 -1
View File
@@ -1,2 +1,2 @@
mod render; mod render;
mod game; pub(crate) mod game;
+10 -1
View File
@@ -2,6 +2,7 @@ use alloc::string::{String, ToString};
use alloc::{format, vec}; use alloc::{format, vec};
use alloc::vec::Vec; use alloc::vec::Vec;
use alloc::boxed::Box; use alloc::boxed::Box;
use alloc::fmt::format;
use alloc::sync::Arc; use alloc::sync::Arc;
use core::any::Any; use core::any::Any;
use async_trait::async_trait; use async_trait::async_trait;
@@ -25,6 +26,9 @@ use super::calc;
const OFFSET_X: i64 = 39; const OFFSET_X: i64 = 39;
const OFFSET_Y: i64 = 10; const OFFSET_Y: i64 = 10;
use core::f64::consts::E;
use core::f64::consts::PI;
#[derive(Clone)] #[derive(Clone)]
pub struct Grapher { pub struct Grapher {
points: Vec<PointF64>, points: Vec<PointF64>,
@@ -155,7 +159,12 @@ impl Grapher {
let x = x as f64 / 100.0; let x = x as f64 / 100.0;
let new_eq = equation.chars().map(|c| { let new_eq = equation.chars().map(|c| {
if c == 'x' { format!("({})", x) } else { c.to_string() } match c {
'x' => format!("({})", x),
'e' => format!("({})", E),
'π' => format!("({})", PI),
_ => c.to_string(),
}
}).collect::<String>(); }).collect::<String>();
let fx = cal.calculate(new_eq); let fx = cal.calculate(new_eq);
+5 -29
View File
@@ -125,6 +125,10 @@ async fn exec() -> Result<(), Error> {
let mut game = snake::Game::new(); let mut game = snake::Game::new();
game.run(args).await?; game.run(args).await?;
} }
"asteroids" => {
let mut asteroid_game = asteroids::game::Game::new();
asteroid_game.run(args).await?;
}
"serial" => { "serial" => {
let c = Serial::reply_char('e'); let c = Serial::reply_char('e');
println!("{}", c); println!("{}", c);
@@ -184,11 +188,8 @@ async fn exec() -> Result<(), Error> {
} }
"test_features" => { "test_features" => {
Screen::Application.set_mode().unwrap(); Screen::Application.set_mode().unwrap();
setup_ui().await; setup_ui().await;
Screen::Terminal.set_mode().unwrap();
Screen::Terminal.set_mode().unwrap()
} }
_ => { _ => {
return Err(Error::UnknownCommand( return Err(Error::UnknownCommand(
@@ -315,31 +316,6 @@ async fn setup_ui() {
} }
async fn test_new_datastore() {
let container = Widget::insert(CgContainer::new(
Position::new(0, 0),
Dimensions::new(80, 25),
true,
));
let textbox = Widget::insert(CgTextBox::new(
String::from("test textbox"),
String::from("dam"),
Position::new(2, 5),
Dimensions::new(40, 12),
true,
));
let mut c = textbox.fetch::<CgTextBox>().unwrap();
c.content = String::from("dam2");
textbox.update(c);
let c = textbox.fetch::<CgTextBox>().unwrap();
serial_println!("{}", c.content);
}
+4 -3
View File
@@ -96,7 +96,8 @@ impl Widget {
impl Drop for Widget { impl Drop for Widget {
fn drop(&mut self) { fn drop(&mut self) {
GUITREE.lock().remove(self); let removed = GUITREE.lock().remove(self);
drop(removed);
} }
} }
@@ -136,9 +137,9 @@ impl DataStore {
items.get(&id.id).cloned() items.get(&id.id).cloned()
} }
fn remove(&self, id: &Widget) { fn remove(&self, id: &Widget) -> Option<Arc<Mutex<dyn CgComponent + Send + Sync>>> {
let mut items = self.items.lock(); let mut items = self.items.lock();
items.remove(&id.id); items.remove(&id.id)
} }
} }
+52 -24
View File
@@ -93,31 +93,61 @@ impl CgTextEdit for CgLineEdit {
#[async_trait] #[async_trait]
impl CgTextInput for CgLineEdit { impl CgTextInput for CgLineEdit {
async fn input(&mut self, break_condition: fn(KeyStroke) -> (KeyStroke, Exit), id: &Widget, app: &Widget) -> Result<(String, bool), RenderError> { async fn input(&mut self, break_condition: fn(KeyStroke) -> (KeyStroke, Exit), id: &Widget, app: &Widget) -> Result<(String, bool), RenderError> {
while let (c, Exit::None) = break_condition(Stdin::keystroke().await) { loop {
match c { match break_condition(Stdin::keystroke().await) {
KeyStroke::Char('\n') => break, (KeyStroke::Char('\n'), Exit::None) => {
KeyStroke::Char('\x08') => self.backspace(), let res = self.text.iter().collect();
KeyStroke::Backspace => self.backspace(), self.clear();
KeyStroke::Char(c) => self.write_char(c), id.update(self.clone());
KeyStroke::Left => self.move_cursor(false), match app.render() {
KeyStroke::Right => self.move_cursor(true), Ok(frame) => frame.write_to_screen()?,
Err(e) => return Err(e),
}
return Ok((res, false))
},
(c, Exit::None) => {
match c {
KeyStroke::Char('\x08') => self.backspace(),
KeyStroke::Backspace => self.backspace(),
KeyStroke::Char(c) => self.write_char(c),
KeyStroke::Left => self.move_cursor(false),
KeyStroke::Right => self.move_cursor(true),
_ => (),
}
id.update(self.clone());
match app.render() {
Ok(frame) => frame.write_to_screen()?,
Err(e) => return Err(e),
}
},
(_, Exit::Exit) => {
return Ok((String::new(), true))
},
_ => (), _ => (),
} }
id.update(self.clone());
match app.render() {
Ok(frame) => frame.write_to_screen()?,
Err(e) => return Err(e),
}
};
let res = self.text.iter().collect();
self.clear();
id.update(self.clone());
match app.render() {
Ok(frame) => frame.write_to_screen()?,
Err(e) => return Err(e),
} }
Ok((res, false)) }
}
#[derive(Debug, Clone)]
pub struct CgBoxEdit {
pub position: Position,
pub dimensions: Dimensions,
pub prompt: String,
pub text: Vec<char>,
pub ptr: Position,
}
impl CgBoxEdit {
pub fn new(position: Position, dimensions: Dimensions, prompt: String) -> CgBoxEdit {
CgBoxEdit {
position,
dimensions,
prompt,
text: Vec::new(),
ptr: Position::new(0, 0)
}
} }
} }
@@ -137,5 +167,3 @@ impl CgTextInput for CgLineEdit {
-5
View File
@@ -58,12 +58,7 @@ impl CgOutline for CgContainer {
impl CgComponent for CgContainer { impl CgComponent for CgContainer {
fn render(&self) -> Result<Frame, RenderError> { fn render(&self) -> Result<Frame, RenderError> {
serial_println!("rendering");
let mut result = Frame::new(self.position, self.dimensions)?; let mut result = Frame::new(self.position, self.dimensions)?;
serial_println!("{:?}", self.elements);
for widget in &self.elements { for widget in &self.elements {
let frame = widget.1.render()?; let frame = widget.1.render()?;
match result.render_bounds_check(&frame, true) { // TODO: this needs to be set to false for production match result.render_bounds_check(&frame, true) { // TODO: this needs to be set to false for production