several fixes and changes
This commit is contained in:
Generated
+1
@@ -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",
|
||||||
|
|||||||
@@ -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
@@ -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
|
||||||
|
|||||||
@@ -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,2 +1,2 @@
|
|||||||
mod render;
|
mod render;
|
||||||
mod game;
|
pub(crate) mod game;
|
||||||
+10
-1
@@ -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
@@ -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);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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 {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user