- added a new API for switching between terminal and application mode
- removed unneeded imports to reduce the dumb amount of warnings from the compiler - added a bounds check in frame.rs to avoid a panic when a frame tries to render a character out of bounds, instead returning an error
This commit is contained in:
@@ -7,12 +7,9 @@
|
|||||||
#![feature(alloc_error_handler)]
|
#![feature(alloc_error_handler)]
|
||||||
#![feature(async_fn_in_trait)]
|
#![feature(async_fn_in_trait)]
|
||||||
#![feature(async_closure)]
|
#![feature(async_closure)]
|
||||||
#![feature(global_asm)]
|
|
||||||
#![feature(inherent_associated_types)]
|
#![feature(inherent_associated_types)]
|
||||||
|
|
||||||
|
|
||||||
use alloc::string::String;
|
|
||||||
use alloc::vec;
|
|
||||||
use bootloader::{entry_point, BootInfo};
|
use bootloader::{entry_point, BootInfo};
|
||||||
use core::panic::PanicInfo;
|
use core::panic::PanicInfo;
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
@@ -23,7 +20,6 @@ pub mod user;
|
|||||||
pub use system::std as std;
|
pub use system::std as std;
|
||||||
pub use user::bin::*;
|
pub use user::bin::*;
|
||||||
use crate::calc::Calculator;
|
use crate::calc::Calculator;
|
||||||
use crate::std::application::Application;
|
|
||||||
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
|
|||||||
+1
-5
@@ -7,7 +7,7 @@
|
|||||||
use bootloader::{entry_point, BootInfo};
|
use bootloader::{entry_point, BootInfo};
|
||||||
use core::panic::PanicInfo;
|
use core::panic::PanicInfo;
|
||||||
use CrystalOS::std::tasks::{Executor, Task};
|
use CrystalOS::std::tasks::{Executor, Task};
|
||||||
use CrystalOS::{print, print_log, printerr, println, println_log, std::syscall};
|
use CrystalOS::{printerr, std::syscall};
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
use CrystalOS::user::bin::shell;
|
use CrystalOS::user::bin::shell;
|
||||||
|
|
||||||
@@ -40,9 +40,5 @@ fn main(boot_info: &'static BootInfo) -> ! {
|
|||||||
loop {
|
loop {
|
||||||
executor.try_run();
|
executor.try_run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
loop {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
use x86_64::structures::idt::{InterruptDescriptorTable, InterruptStackFrame};
|
use x86_64::structures::idt::{InterruptDescriptorTable, InterruptStackFrame};
|
||||||
use crate::{print, println};
|
use crate::println;
|
||||||
use super::gdt;
|
use super::gdt;
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
use spin;
|
use spin;
|
||||||
@@ -28,7 +28,7 @@ extern "x86-interrupt" fn timer_interrupt_handler(_stack_frame: InterruptStackFr
|
|||||||
|
|
||||||
extern "x86-interrupt" fn keyboard_interrupt_handler(_stack_frame: InterruptStackFrame) {
|
extern "x86-interrupt" fn keyboard_interrupt_handler(_stack_frame: InterruptStackFrame) {
|
||||||
|
|
||||||
use pc_keyboard::{layouts, DecodedKey, HandleControl, Keyboard, ScancodeSet1};
|
use pc_keyboard::{layouts, HandleControl, Keyboard, ScancodeSet1};
|
||||||
use spin::Mutex;
|
use spin::Mutex;
|
||||||
use x86_64::instructions::port::Port;
|
use x86_64::instructions::port::Port;
|
||||||
|
|
||||||
@@ -38,7 +38,7 @@ extern "x86-interrupt" fn keyboard_interrupt_handler(_stack_frame: InterruptStac
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut keyboard = KEYBOARD.lock();
|
let keyboard = KEYBOARD.lock();
|
||||||
let mut port = Port::new(0x60);
|
let mut port = Port::new(0x60);
|
||||||
let scancode: u8 = unsafe { port.read() };
|
let scancode: u8 = unsafe { port.read() };
|
||||||
|
|
||||||
|
|||||||
@@ -3,12 +3,8 @@ use lazy_static::lazy_static;
|
|||||||
use spin::Mutex;
|
use spin::Mutex;
|
||||||
use volatile::Volatile;
|
use volatile::Volatile;
|
||||||
|
|
||||||
use alloc::borrow::ToOwned;
|
|
||||||
use alloc::vec;
|
use alloc::vec;
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
use crate::system::kernel::render::RenderError::InvalidRenderMode;
|
|
||||||
use crate::serial_println;
|
|
||||||
use crate::std::io::Screen;
|
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
@@ -137,24 +133,14 @@ impl Renderer {
|
|||||||
self.internal_render();
|
self.internal_render();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn application_mode(&mut self) -> Result<(), RenderError> {
|
pub fn application_mode(&mut self) {
|
||||||
if self.application_mode {
|
self.application_mode = true;
|
||||||
return Err(InvalidRenderMode);
|
self.internal_render();
|
||||||
} else {
|
|
||||||
self.application_mode = true;
|
|
||||||
self.internal_render();
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn terminal_mode(&mut self) -> Result<(), RenderError> {
|
pub fn terminal_mode(&mut self) {
|
||||||
if !self.application_mode {
|
self.application_mode = false;
|
||||||
return Err(InvalidRenderMode);
|
self.internal_render();
|
||||||
} else {
|
|
||||||
self.application_mode = false;
|
|
||||||
self.internal_render();
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mode_is_app(&self) -> bool {
|
pub fn mode_is_app(&self) -> bool {
|
||||||
@@ -210,10 +196,10 @@ impl Renderer {
|
|||||||
|
|
||||||
pub fn cursor_position(&mut self, x: u8, y: u8) -> Result<(), RenderError> {
|
pub fn cursor_position(&mut self, x: u8, y: u8) -> Result<(), RenderError> {
|
||||||
// check that x and y are within bounds
|
// check that x and y are within bounds
|
||||||
if x >= 80 || x < 0 || y >= 25 || y < 0 {
|
if x >= 80 || y >= 25 {
|
||||||
return Err(RenderError::OutOfBounds(
|
return Err(RenderError::OutOfBounds(
|
||||||
x >= 80 || x < 0,
|
x >= 80,
|
||||||
y >= 25 || y < 0
|
y >= 25
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
self.internal_set_cursor_position(x, y);
|
self.internal_set_cursor_position(x, y);
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ pub fn _serial_print(args: core::fmt::Arguments) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
pub fn serial_reply(chr: char) -> char {
|
pub fn serial_reply(chr: char) -> char {
|
||||||
use core::fmt::Write;
|
|
||||||
use x86_64::instructions::interrupts;
|
use x86_64::instructions::interrupts;
|
||||||
|
|
||||||
let mut chr_return: char = 'X';
|
let mut chr_return: char = 'X';
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
use crate::println;
|
|
||||||
pub fn init() -> Result<(), ()> {
|
pub fn init() -> Result<(), ()> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -5,7 +5,7 @@ use x86_64::instructions::interrupts;
|
|||||||
|
|
||||||
use conquer_once::spin::OnceCell;
|
use conquer_once::spin::OnceCell;
|
||||||
use crossbeam_queue::ArrayQueue;
|
use crossbeam_queue::ArrayQueue;
|
||||||
use crate::{println, serial_println};
|
use crate::println;
|
||||||
|
|
||||||
use core::{pin::Pin, task::{Poll, Context}};
|
use core::{pin::Pin, task::{Poll, Context}};
|
||||||
use futures_util::stream::Stream;
|
use futures_util::stream::Stream;
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ use alloc::string::String;
|
|||||||
use alloc::vec;
|
use alloc::vec;
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
use crate::system::kernel::render::{RENDERER, ScreenChar};
|
use crate::system::kernel::render::{RENDERER, ScreenChar};
|
||||||
use crate::std::io::{Color, Screen};
|
use crate::std::io::Color;
|
||||||
|
|
||||||
/// TODO: get a working implementation for CLI apps
|
/// TODO: get a working implementation for CLI apps
|
||||||
/// elements can be created using their from_str() method
|
/// elements can be created using their from_str() method
|
||||||
@@ -135,8 +135,12 @@ impl Frame {
|
|||||||
pub fn dimensions(&self) -> Dimensions {
|
pub fn dimensions(&self) -> Dimensions {
|
||||||
self.dimensions
|
self.dimensions
|
||||||
}
|
}
|
||||||
pub fn write(&mut self, position: Position, char: ColouredChar) {
|
pub fn write(&mut self, position: Position, char: ColouredChar) -> Result<(), RenderError> {
|
||||||
self.frame[position.y][position.x] = char
|
if position.x >= self.dimensions.x || position.y >= self.dimensions.y {
|
||||||
|
return Err(RenderError::OutOfBounds(true, true));
|
||||||
|
}
|
||||||
|
self.frame[position.y][position.x] = char;
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
pub fn place_child_element(&mut self, other: &Frame) {
|
pub fn place_child_element(&mut self, other: &Frame) {
|
||||||
for (i, row) in other.frame.iter().enumerate() {
|
for (i, row) in other.frame.iter().enumerate() {
|
||||||
|
|||||||
+26
-4
@@ -48,13 +48,15 @@ pub enum Screen {
|
|||||||
Terminal,
|
Terminal,
|
||||||
Application,
|
Application,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// DEPRECATED - STOP USING THIS SOON
|
||||||
impl Screen {
|
impl Screen {
|
||||||
/// mode can be set for the kernel using this method
|
/// mode can be set for the kernel using this method
|
||||||
pub fn set_mode(&self) -> Result<(), RenderError> {
|
pub fn set_mode(&self) -> Result<(), RenderError> {
|
||||||
match self {
|
Ok(match self {
|
||||||
Screen::Terminal => RENDERER.lock().terminal_mode(),
|
Screen::Terminal => RENDERER.lock().terminal_mode(),
|
||||||
Screen::Application => RENDERER.lock().application_mode(),
|
Screen::Application => RENDERER.lock().application_mode(),
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// returns the current display mode
|
/// returns the current display mode
|
||||||
@@ -68,9 +70,9 @@ impl Screen {
|
|||||||
/// switches between modes
|
/// switches between modes
|
||||||
pub fn switch(&self) {
|
pub fn switch(&self) {
|
||||||
if RENDERER.lock().mode_is_app() == true {
|
if RENDERER.lock().mode_is_app() == true {
|
||||||
RENDERER.lock().terminal_mode().unwrap();
|
RENDERER.lock().terminal_mode();
|
||||||
} else {
|
} else {
|
||||||
RENDERER.lock().application_mode().unwrap();
|
RENDERER.lock().application_mode();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn clear() {
|
pub fn clear() {
|
||||||
@@ -78,6 +80,26 @@ impl Screen {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// An interface that tells the kernel what rendering mode to use
|
||||||
|
/// Creating an instance of this struct will enable application rendering mode
|
||||||
|
/// Dropping the instance will return the display to focus on the terminal.
|
||||||
|
pub struct Display;
|
||||||
|
|
||||||
|
impl Display {
|
||||||
|
pub fn borrow() -> Display {
|
||||||
|
RENDERER.lock().application_mode();
|
||||||
|
Display
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drop for Display {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
RENDERER.lock().terminal_mode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! println_log {
|
macro_rules! println_log {
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
use alloc::{string::{String, ToString}, vec::Vec};
|
use alloc::{string::{String, ToString}, vec::Vec};
|
||||||
use core::ops::Index;
|
use rand::{SeedableRng, rngs::SmallRng, RngCore};
|
||||||
use rand::{Rng, SeedableRng, rngs::SmallRng, RngCore};
|
|
||||||
use spin::Mutex;
|
use spin::Mutex;
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
use cmos_rtc::{ReadRTC, Time};
|
use cmos_rtc::{ReadRTC, Time};
|
||||||
|
|||||||
@@ -1,6 +1,3 @@
|
|||||||
use core::time::Duration;
|
|
||||||
use embedded_time::{Clock, Timer};
|
|
||||||
use cmos_rtc::{ReadRTC, Time};
|
|
||||||
use crate::println;
|
use crate::println;
|
||||||
use super::super::kernel::interrupts::GLOBALTIMER;
|
use super::super::kernel::interrupts::GLOBALTIMER;
|
||||||
use x86_64::instructions::interrupts;
|
use x86_64::instructions::interrupts;
|
||||||
|
|||||||
@@ -292,13 +292,7 @@ impl GameTimer {
|
|||||||
self.time_since_spawn += 1;
|
self.time_since_spawn += 1;
|
||||||
self.time_since_move += 1;
|
self.time_since_move += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_spawn_time(&self) -> u32 {
|
|
||||||
self.time_since_spawn
|
|
||||||
}
|
|
||||||
pub fn reset_spawn_time(&mut self) {
|
|
||||||
self.time_since_spawn = 0
|
|
||||||
}
|
|
||||||
pub fn get_move_time(&self) -> u32 {
|
pub fn get_move_time(&self) -> u32 {
|
||||||
self.time_since_move
|
self.time_since_move
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,15 +5,12 @@ use alloc::borrow::ToOwned;
|
|||||||
use crate::{println, print, mknode, std};
|
use crate::{println, print, mknode, std};
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use lazy_static::lazy_static;
|
|
||||||
use crate::std::application::{
|
use crate::std::application::{
|
||||||
Application,
|
Application,
|
||||||
Error as ShellError
|
Error as ShellError
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct Parser {
|
struct Parser {
|
||||||
tokens: Vec<Token>,
|
tokens: Vec<Token>,
|
||||||
idx: i32,
|
idx: i32,
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
use alloc::format;
|
use alloc::format;
|
||||||
use alloc::string::String;
|
use alloc::string::String;
|
||||||
use crate::println;
|
|
||||||
|
|
||||||
const PI: f64 = 3.14159265358979323846264338327950288419716939937510;
|
const PI: f64 = 3.14159265358979323846264338327950288419716939937510;
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use alloc::{boxed::Box, format, string::String, vec::Vec};
|
use alloc::{boxed::Box, format, string::String, vec::Vec};
|
||||||
use log::info;
|
|
||||||
|
|
||||||
use crate::{std::os::OS, std::io::{Color, write, Screen}, println, std::application::{
|
use crate::std::{
|
||||||
Application,
|
os::OS,
|
||||||
Error,
|
io::{Color, write, Screen},
|
||||||
}, std};
|
application::{Application, Error},
|
||||||
|
};
|
||||||
|
use crate::println;
|
||||||
|
|
||||||
const CRYSTAL_LOGO: &str =
|
const CRYSTAL_LOGO: &str =
|
||||||
"\n $$$$$$\\ $$\\ $$\\ $$$$$$\\ $$$$$$\\
|
"\n $$$$$$\\ $$\\ $$\\ $$$$$$\\ $$$$$$\\
|
||||||
|
|||||||
+146
-146
@@ -1,146 +1,146 @@
|
|||||||
use alloc::{boxed::Box, string::String, vec::Vec};
|
// use alloc::{boxed::Box, string::String, vec::Vec};
|
||||||
use core::cmp::min;
|
// use core::cmp::min;
|
||||||
|
//
|
||||||
struct Player {
|
// struct Player {
|
||||||
username: String,
|
// username: String,
|
||||||
stats: EntityStats,
|
// stats: EntityStats,
|
||||||
|
//
|
||||||
exp: u32,
|
// exp: u32,
|
||||||
level: u32,
|
// level: u32,
|
||||||
skill_points: u32,
|
// skill_points: u32,
|
||||||
skills: Vec<Box<dyn Skill>>,
|
// skills: Vec<Box<dyn Skill>>,
|
||||||
|
//
|
||||||
helmet: Option<Helmet>,
|
// helmet: Option<Helmet>,
|
||||||
chestplate: Option<Chestplate>,
|
// chestplate: Option<Chestplate>,
|
||||||
boots: Option<Boots>,
|
// boots: Option<Boots>,
|
||||||
|
//
|
||||||
inventory: Vec<Item>,
|
// inventory: Vec<Item>,
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
struct EntityStats {
|
// struct EntityStats {
|
||||||
health: i32,
|
// health: i32,
|
||||||
max_health: i32,
|
// max_health: i32,
|
||||||
mana: i32,
|
// mana: i32,
|
||||||
max_mana: i32,
|
// max_mana: i32,
|
||||||
defence: i32,
|
// defence: i32,
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
impl Player {
|
// impl Player {
|
||||||
fn new(username: String) -> Self {
|
// fn new(username: String) -> Self {
|
||||||
Self {
|
// Self {
|
||||||
username,
|
// username,
|
||||||
stats: EntityStats {
|
// stats: EntityStats {
|
||||||
health: 100,
|
// health: 100,
|
||||||
max_health: 100,
|
// max_health: 100,
|
||||||
mana: 100,
|
// mana: 100,
|
||||||
max_mana: 100,
|
// max_mana: 100,
|
||||||
defence: 0,
|
// defence: 0,
|
||||||
},
|
// },
|
||||||
exp: 0,
|
// exp: 0,
|
||||||
level: 0,
|
// level: 0,
|
||||||
skill_points: 0,
|
// skill_points: 0,
|
||||||
skills: Vec::new(),
|
// skills: Vec::new(),
|
||||||
|
//
|
||||||
helmet: None,
|
// helmet: None,
|
||||||
chestplate: None,
|
// chestplate: None,
|
||||||
boots: None,
|
// boots: None,
|
||||||
inventory: Vec::new(),
|
// inventory: Vec::new(),
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
fn heal(&mut self, amount: i32) {
|
// fn heal(&mut self, amount: i32) {
|
||||||
let max_health = self.max_health();
|
// let max_health = self.max_health();
|
||||||
|
//
|
||||||
self.stats.health = min(self.stats.health + amount, max_health);
|
// self.stats.health = min(self.stats.health + amount, max_health);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
fn damage(&mut self, amount: i32) {
|
// fn damage(&mut self, amount: i32) {
|
||||||
let hp = self.health_points();
|
// let hp = self.health_points();
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
fn inventory_contents_mut(&mut self) -> &mut Vec<Item> {
|
// fn inventory_contents_mut(&mut self) -> &mut Vec<Item> {
|
||||||
&mut self.inventory
|
// &mut self.inventory
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
fn max_health(&self) -> i32 {
|
// fn max_health(&self) -> i32 {
|
||||||
let mut max_health = self.stats.max_health;
|
// let mut max_health = self.stats.max_health;
|
||||||
|
//
|
||||||
if let Some(helmet) = &self.helmet {
|
// if let Some(helmet) = &self.helmet {
|
||||||
max_health += helmet.stats.health_bonus;
|
// max_health += helmet.stats.health_bonus;
|
||||||
}
|
// }
|
||||||
if let Some(chestplate) = &self.chestplate {
|
// if let Some(chestplate) = &self.chestplate {
|
||||||
max_health += chestplate.stats.health_bonus;
|
// max_health += chestplate.stats.health_bonus;
|
||||||
}
|
// }
|
||||||
if let Some(boots) = &self.boots {
|
// if let Some(boots) = &self.boots {
|
||||||
max_health += boots.stats.health_bonus;
|
// max_health += boots.stats.health_bonus;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
max_health
|
// max_health
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
fn health_points(&self) -> i32 {
|
// fn health_points(&self) -> i32 {
|
||||||
let mut hp = self.stats.health;
|
// let mut hp = self.stats.health;
|
||||||
if let Some(helmet) = &self.helmet {
|
// if let Some(helmet) = &self.helmet {
|
||||||
hp += helmet.stats.health_bonus;
|
// hp += helmet.stats.health_bonus;
|
||||||
}
|
// }
|
||||||
if let Some(chestplate) = &self.chestplate {
|
// if let Some(chestplate) = &self.chestplate {
|
||||||
hp += chestplate.stats.health_bonus;
|
// hp += chestplate.stats.health_bonus;
|
||||||
}
|
// }
|
||||||
if let Some(boots) = &self.boots {
|
// if let Some(boots) = &self.boots {
|
||||||
hp += boots.stats.health_bonus;
|
// hp += boots.stats.health_bonus;
|
||||||
}
|
// }
|
||||||
hp
|
// hp
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
enum Item {
|
// enum Item {
|
||||||
Helmet(Helmet),
|
// Helmet(Helmet),
|
||||||
Chestplate(Chestplate),
|
// Chestplate(Chestplate),
|
||||||
Boots(Boots),
|
// Boots(Boots),
|
||||||
Sword,
|
// Sword,
|
||||||
Potion,
|
// Potion,
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
struct Helmet {
|
// struct Helmet {
|
||||||
name: &'static str,
|
// name: &'static str,
|
||||||
lore: &'static str,
|
// lore: &'static str,
|
||||||
stats: ArmourStats,
|
// stats: ArmourStats,
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
struct Chestplate {
|
// struct Chestplate {
|
||||||
name: &'static str,
|
// name: &'static str,
|
||||||
lore: &'static str,
|
// lore: &'static str,
|
||||||
stats: ArmourStats,
|
// stats: ArmourStats,
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
struct Boots {
|
// struct Boots {
|
||||||
name: &'static str,
|
// name: &'static str,
|
||||||
lore: &'static str,
|
// lore: &'static str,
|
||||||
stats: ArmourStats,
|
// stats: ArmourStats,
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
struct ArmourStats {
|
// struct ArmourStats {
|
||||||
durability: i32,
|
// durability: i32,
|
||||||
max_durability: i32,
|
// max_durability: i32,
|
||||||
defence: i32,
|
// defence: i32,
|
||||||
health_bonus: i32,
|
// health_bonus: i32,
|
||||||
mana_bonus: i32,
|
// mana_bonus: i32,
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
struct PlayerStats {}
|
// struct PlayerStats {}
|
||||||
|
//
|
||||||
trait Skill {
|
// trait Skill {
|
||||||
fn skill_name(&self) -> &str; // returns the name of the skill
|
// fn skill_name(&self) -> &str; // returns the name of the skill
|
||||||
fn skill_level(&self) -> &str; // returns the level of that skill
|
// fn skill_level(&self) -> &str; // returns the level of that skill
|
||||||
fn description(&self) -> &str; // returns the status of that skill
|
// fn description(&self) -> &str; // returns the status of that skill
|
||||||
fn skillpoint_level_req(&self) -> i32;
|
// fn skillpoint_level_req(&self) -> i32;
|
||||||
fn increase_level(&mut self, level: &u32, skill_points: &mut u32) -> Result<(), GameError>;
|
// fn increase_level(&mut self, level: &u32, skill_points: &mut u32) -> Result<(), GameError>;
|
||||||
fn decrease_level(&mut self, skill_points: &mut u32) -> Result<(), GameError>;
|
// fn decrease_level(&mut self, skill_points: &mut u32) -> Result<(), GameError>;
|
||||||
fn modify_stats(&self, stats: EntityStats) -> EntityStats;
|
// fn modify_stats(&self, stats: EntityStats) -> EntityStats;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
enum GameError {
|
// enum GameError {
|
||||||
SkillLevelMaxed,
|
// SkillLevelMaxed,
|
||||||
InsufficientSkillPoints,
|
// InsufficientSkillPoints,
|
||||||
InsufficientLevel,
|
// InsufficientLevel,
|
||||||
}
|
// }
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
use alloc::borrow::ToOwned;
|
|
||||||
use alloc::string::String;
|
use alloc::string::String;
|
||||||
use alloc::vec;
|
use alloc::vec;
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
@@ -6,9 +5,8 @@ use alloc::boxed::Box;
|
|||||||
use crate::std::application::{Application, Error};
|
use crate::std::application::{Application, Error};
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use crate::std::frame::{ColouredChar, Frame, Position, Dimensions, RenderError};
|
use crate::std::frame::{ColouredChar, Frame, Position, Dimensions, RenderError};
|
||||||
use crate::std::io::{KeyStroke, Screen, Stdin, Color, ColorCode};
|
use crate::std::io::{KeyStroke, Stdin, Color, ColorCode, Display};
|
||||||
use crate::std::time::wait;
|
use crate::std::time::wait;
|
||||||
use crate::user::bin::snake::Game;
|
|
||||||
|
|
||||||
pub struct GameOfLife {
|
pub struct GameOfLife {
|
||||||
frame: Frame
|
frame: Frame
|
||||||
@@ -25,7 +23,7 @@ impl Application for GameOfLife {
|
|||||||
}
|
}
|
||||||
async fn run(&mut self, args: Vec<String>) -> Result<(), Error> {
|
async fn run(&mut self, args: Vec<String>) -> Result<(), Error> {
|
||||||
// setup:
|
// setup:
|
||||||
Screen::Application.set_mode();
|
let d = Display::borrow();
|
||||||
|
|
||||||
let xoffset = 38;
|
let xoffset = 38;
|
||||||
let yoffset = 5;
|
let yoffset = 5;
|
||||||
@@ -56,7 +54,6 @@ impl Application for GameOfLife {
|
|||||||
|
|
||||||
self.mainloop()?;
|
self.mainloop()?;
|
||||||
|
|
||||||
Screen::Terminal.set_mode();
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,6 @@ use async_trait::async_trait;
|
|||||||
use alloc::{boxed::Box, string::String, vec::Vec};
|
use alloc::{boxed::Box, string::String, vec::Vec};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
std::os::OS,
|
|
||||||
std::io::{Color, write},
|
|
||||||
println,
|
println,
|
||||||
std::application::{
|
std::application::{
|
||||||
Application,
|
Application,
|
||||||
|
|||||||
+4
-10
@@ -2,17 +2,11 @@ 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 core::any::Any;
|
use core::any::Any;
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use spin::Mutex;
|
|
||||||
use crate::{println, serial_println};
|
|
||||||
use crate::std::io::{ColorCode};
|
|
||||||
use crate::shell::command_handler;
|
|
||||||
use crate::std::application::{Application, Error};
|
use crate::std::application::{Application, Error};
|
||||||
use crate::std::frame::{self, Frame, Position, Dimensions, ColouredChar, RenderError};
|
use crate::std::frame::{Frame, Position, Dimensions, ColouredChar, RenderError};
|
||||||
use crate::std::io::{Color, KeyStroke, Screen, Stdin};
|
use crate::std::io::{KeyStroke, Screen, Stdin};
|
||||||
|
|
||||||
use crate::user::lib::libgui::{
|
use crate::user::lib::libgui::{
|
||||||
cg_core::{CgComponent},
|
cg_core::{CgComponent},
|
||||||
@@ -100,7 +94,7 @@ impl Application for Grapher {
|
|||||||
|
|
||||||
while let c = Stdin::keystroke().await {
|
while let c = Stdin::keystroke().await {
|
||||||
|
|
||||||
let mut entry_widget = container.elements.get("entry_box").unwrap();
|
let entry_widget = container.elements.get("entry_box").unwrap();
|
||||||
let mut entry = entry_widget.fetch::<CgLineEdit>().unwrap();
|
let mut entry = entry_widget.fetch::<CgLineEdit>().unwrap();
|
||||||
|
|
||||||
rerender = true;
|
rerender = true;
|
||||||
@@ -196,7 +190,7 @@ impl Grapher {
|
|||||||
|
|
||||||
let offset_x = point.x + OFFSET_X;
|
let offset_x = point.x + OFFSET_X;
|
||||||
let offset_y = point.y + OFFSET_Y;
|
let offset_y = point.y + OFFSET_Y;
|
||||||
self.frame.write(Position::new(offset_x as usize, 21-offset_y as usize), ColouredChar::new('*'));
|
self.frame.write(Position::new(offset_x as usize, 21-offset_y as usize), ColouredChar::new('*')).expect("Failed to write to frame - this function is broken.");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reset_frame(&mut self) {
|
fn reset_frame(&mut self) {
|
||||||
|
|||||||
+56
-12
@@ -1,12 +1,15 @@
|
|||||||
use alloc::boxed::Box;
|
use alloc::boxed::Box;
|
||||||
use alloc::string::String;
|
use alloc::string::String;
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
|
use core::any::Any;
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use core::fmt::Write;
|
|
||||||
use crate::std::application::{Application, Error};
|
use crate::std::application::{Application, Error};
|
||||||
use crate::std;
|
use crate::std;
|
||||||
|
use crate::std::frame::{ColouredChar, Dimensions, Frame, Position, RenderError};
|
||||||
|
use crate::std::io::{Display, KeyStroke, Stdin};
|
||||||
|
use crate::user::lib::libgui::cg_core::CgComponent;
|
||||||
|
|
||||||
struct Game {
|
pub(crate) struct Game {
|
||||||
ball: Ball,
|
ball: Ball,
|
||||||
player1: Player,
|
player1: Player,
|
||||||
player2: Player,
|
player2: Player,
|
||||||
@@ -18,40 +21,81 @@ impl Application for Game {
|
|||||||
Game {
|
Game {
|
||||||
ball: Ball::new(),
|
ball: Ball::new(),
|
||||||
player1: Player::new(1),
|
player1: Player::new(1),
|
||||||
player2: Player::new(2),
|
player2: Player::new(78),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run(&mut self, _: Vec<String>) -> Result<(), Error> {
|
async fn run(&mut self, _: Vec<String>) -> Result<(), Error> {
|
||||||
|
let d = Display::borrow();
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
self.ball.update(&self.player1, &self.player2);
|
std::time::wait(0.01);
|
||||||
|
|
||||||
|
if let Some(key) = Stdin::try_keystroke() {
|
||||||
|
match key {
|
||||||
|
KeyStroke::Char('w') => {
|
||||||
|
self.player1.pos.y -= 1;
|
||||||
|
},
|
||||||
|
KeyStroke::Char('s') => {
|
||||||
|
self.player1.pos.y += 1;
|
||||||
|
},
|
||||||
|
KeyStroke::Up => {
|
||||||
|
self.player2.pos.y -= 1;
|
||||||
|
},
|
||||||
|
KeyStroke::Down => {
|
||||||
|
self.player2.pos.y += 1;
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let Ok(frame) = self.render() {
|
||||||
|
frame.write_to_screen().unwrap();
|
||||||
|
}
|
||||||
|
// self.ball.update(&self.player1, &self.player2);
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl CgComponent for Game {
|
||||||
|
fn render(&self) -> Result<Frame, RenderError> {
|
||||||
|
let mut frame = Frame::new(Dimensions::new(0, 0), Dimensions::new(80, 25))?;
|
||||||
|
|
||||||
|
frame.write(self.player1.pos, ColouredChar::new('@')).unwrap();
|
||||||
|
frame.write(self.player2.pos, ColouredChar::new('@')).unwrap();
|
||||||
|
frame.write(self.ball.pos, ColouredChar::new('@')).unwrap();
|
||||||
|
|
||||||
|
Ok(frame)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn as_any(&self) -> &dyn Any {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct Player {
|
struct Player {
|
||||||
x: i32,
|
pos: Position,
|
||||||
y: i32,
|
|
||||||
score: i32,
|
score: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Player {
|
impl Player {
|
||||||
fn new(y: i32) -> Self {
|
fn new(x: usize) -> Self {
|
||||||
Player { x: 0, y, score: 0 }
|
Player { pos: Position::new(x, 12), score: 0 }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Ball {
|
struct Ball {
|
||||||
x: i32,
|
pos: Position,
|
||||||
y: i32,
|
vx: i32,
|
||||||
|
vy: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Ball {
|
impl Ball {
|
||||||
fn new() -> Self {
|
fn new() -> Self {
|
||||||
Ball { x: 0, y: 0 }
|
Ball { pos: Position::new(40, 12), vx: 1, vy: 0 }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update(&mut self, player1: &Player, player2: &Player) {
|
fn update(&mut self, player1: &Player, player2: &Player) {
|
||||||
self.x += 1;
|
self.pos.x = (self.pos.x as i32 + self.vx) as usize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ const RICKROLL2: &str = "
|
|||||||
1a###w#*mObo*oatXkW*oo#*###p `--' `---' `----' `-----' | |-'
|
1a###w#*mObo*oatXkW*oo#*###p `--' `---' `----' `-----' | |-'
|
||||||
`--'";
|
`--'";
|
||||||
|
|
||||||
use crate::{println, serial_println};
|
use crate::println;
|
||||||
use alloc::{string::String, boxed::Box, vec::Vec};
|
use alloc::{string::String, boxed::Box, vec::Vec};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+8
-13
@@ -1,33 +1,26 @@
|
|||||||
use async_trait::async_trait;
|
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
use spin::Mutex;
|
use spin::Mutex;
|
||||||
|
|
||||||
use alloc::{boxed::Box, format, string::{String, ToString}, vec, vec::Vec};
|
use alloc::{boxed::Box, format, string::{String, ToString}, vec, vec::Vec};
|
||||||
use futures_util::TryFutureExt;
|
use vga::writers::{PrimitiveDrawing};
|
||||||
use vga::writers::{GraphicsWriter, PrimitiveDrawing};
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
print,
|
|
||||||
printerr,
|
printerr,
|
||||||
println,
|
println,
|
||||||
serial_println,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::std::{
|
use crate::std::{
|
||||||
application::{Application, Error, Exit},
|
application::{Application, Error, Exit},
|
||||||
time::{timer, wait},
|
time::{timer, wait},
|
||||||
random::Random,
|
|
||||||
io::{
|
io::{
|
||||||
Color, write, Screen, Stdin, Serial, KeyStroke
|
Color, write, Screen, Stdin, Serial, KeyStroke
|
||||||
},
|
},
|
||||||
frame::{Dimensions, Position, ColorCode},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::user::{
|
use crate::user::{
|
||||||
lib::libgui::{
|
lib::libgui::{
|
||||||
cg_core::{CgComponent, CgTextEdit, CgKeyboardCapture, CgTextInput, Widget},
|
cg_core::{CgComponent, CgKeyboardCapture},
|
||||||
cg_widgets::{CgTextBox, CgContainer, CgLabel, CgStatusBar, CgDialog},
|
cg_widgets::CgDialog,
|
||||||
cg_inputs::CgLineEdit,
|
|
||||||
},
|
},
|
||||||
bin::*,
|
bin::*,
|
||||||
};
|
};
|
||||||
@@ -140,6 +133,9 @@ async fn exec() -> Result<(), Error> {
|
|||||||
let mut asteroid_game = asteroids::Game::new();
|
let mut asteroid_game = asteroids::Game::new();
|
||||||
asteroid_game.run(args).await?;
|
asteroid_game.run(args).await?;
|
||||||
}
|
}
|
||||||
|
"pong" => {
|
||||||
|
pong::Game::new().run(args).await?;
|
||||||
|
}
|
||||||
"serial" => {
|
"serial" => {
|
||||||
let c = Serial::reply_char('e');
|
let c = Serial::reply_char('e');
|
||||||
println!("{}", c);
|
println!("{}", c);
|
||||||
@@ -149,8 +145,8 @@ async fn exec() -> Result<(), Error> {
|
|||||||
game.run(Vec::new()).await?;
|
game.run(Vec::new()).await?;
|
||||||
}
|
}
|
||||||
"tetris" => {
|
"tetris" => {
|
||||||
let mut game = tetris::TetrisEngine::new();
|
// let mut game = tetris::TetrisEngine::new();
|
||||||
game.run(Vec::new()).await?;
|
// game.run(Vec::new()).await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
"gigachad?" => {
|
"gigachad?" => {
|
||||||
@@ -192,7 +188,6 @@ async fn exec() -> Result<(), Error> {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
"time" => {
|
"time" => {
|
||||||
use crate::std::time::timer;
|
|
||||||
timer();
|
timer();
|
||||||
}
|
}
|
||||||
"test_features" => {
|
"test_features" => {
|
||||||
|
|||||||
+6
-16
@@ -1,19 +1,13 @@
|
|||||||
use alloc::string::{String, ToString};
|
use alloc::string::String;
|
||||||
use alloc::{format, vec, vec::Vec, boxed::Box};
|
use alloc::{format, vec, vec::Vec, boxed::Box};
|
||||||
use alloc::borrow::ToOwned;
|
|
||||||
use core::arch::x86_64::_mm_test_all_ones;
|
|
||||||
use core::cell::RefCell;
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use crate::std::io::{Color, KeyStroke, Screen, Stdin};
|
use crate::std::io::{Color, Display, KeyStroke, Stdin};
|
||||||
use crate::std::time;
|
use crate::std::time;
|
||||||
use crossbeam_queue::SegQueue;
|
|
||||||
use lazy_static::lazy_static;
|
|
||||||
use crate::{println, serial_println};
|
|
||||||
use crate::std::application::{Application, Error};
|
use crate::std::application::{Application, Error};
|
||||||
use crate::std::frame::{ColouredChar, Dimensions, Frame, RenderError, ColorCode};
|
use crate::std::frame::{ColouredChar, Dimensions, Frame, RenderError, ColorCode};
|
||||||
use crate::std::random::Random;
|
use crate::std::random::Random;
|
||||||
use crate::system::std::frame;
|
use crate::system::std::frame;
|
||||||
use super::super::lib::coords::{Line, Position, Direction};
|
use super::super::lib::coords::{Position, Direction};
|
||||||
|
|
||||||
#[derive(PartialEq)]
|
#[derive(PartialEq)]
|
||||||
enum Gamemode {
|
enum Gamemode {
|
||||||
@@ -53,10 +47,10 @@ impl Application for Game {
|
|||||||
|
|
||||||
async fn run(&mut self, args: Vec<String>) -> Result<(), Error> {
|
async fn run(&mut self, args: Vec<String>) -> Result<(), Error> {
|
||||||
|
|
||||||
let mut settings = [0, 0, 0]; // ai_count, snake_len, poi_count
|
let settings = [0, 0, 0]; // ai_count, snake_len, poi_count
|
||||||
|
|
||||||
if args.len() == 0 {
|
if args.len() == 0 {
|
||||||
self.gamemode == Gamemode::SinglePlayer;
|
self.gamemode = Gamemode::SinglePlayer;
|
||||||
} else {
|
} else {
|
||||||
match args[0].as_str() {
|
match args[0].as_str() {
|
||||||
"easy" => {
|
"easy" => {
|
||||||
@@ -81,13 +75,11 @@ impl Application for Game {
|
|||||||
self.prepare();
|
self.prepare();
|
||||||
|
|
||||||
// switch OS to application mode
|
// switch OS to application mode
|
||||||
Screen::Application.set_mode();
|
let d = Display::borrow();
|
||||||
// render the initial state of the screen.
|
// render the initial state of the screen.
|
||||||
self.render().map_err(|_| Error::ApplicationError(String::from("failed to render game screen")))?;
|
self.render().map_err(|_| Error::ApplicationError(String::from("failed to render game screen")))?;
|
||||||
// run the game
|
// run the game
|
||||||
self.gameloop().await?;
|
self.gameloop().await?;
|
||||||
// return to the terminal
|
|
||||||
Screen::Terminal.set_mode();
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -356,8 +348,6 @@ impl PathFinder {
|
|||||||
// serial_println!("{:?} {:?} {:?} {:?}", nearest_poi, rel_pos, head, optimal);
|
// serial_println!("{:?} {:?} {:?} {:?}", nearest_poi, rel_pos, head, optimal);
|
||||||
return optimal;
|
return optimal;
|
||||||
}
|
}
|
||||||
|
|
||||||
Direction::None
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn optimal_move(head: &Position, rel_pos: &Position, moves: &Vec<Direction>) -> Direction {
|
fn optimal_move(head: &Position, rel_pos: &Position, moves: &Vec<Direction>) -> Direction {
|
||||||
|
|||||||
@@ -3,12 +3,11 @@ use crate::std::application::{
|
|||||||
Application,
|
Application,
|
||||||
Error
|
Error
|
||||||
};
|
};
|
||||||
use crate::{print, println};
|
use crate::println;
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
use spin::Mutex;
|
use spin::Mutex;
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use alloc::{
|
use alloc::{
|
||||||
string::ToString,
|
|
||||||
borrow::ToOwned,
|
borrow::ToOwned,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -101,13 +100,13 @@ println!("\n-------------------------------------");
|
|||||||
|
|
||||||
impl Tasks {
|
impl Tasks {
|
||||||
fn add_task(&mut self, content: String) {
|
fn add_task(&mut self, content: String) {
|
||||||
TASKS.lock().add(content);
|
TASKS.lock().add(content).unwrap();
|
||||||
}
|
}
|
||||||
fn remove_task(&self, idx: usize) {
|
fn remove_task(&self, idx: usize) {
|
||||||
TASKS.lock().remove(idx);
|
TASKS.lock().remove(idx).unwrap();
|
||||||
}
|
}
|
||||||
fn select_task(&self, idx: i32) {
|
fn select_task(&self, idx: i32) {
|
||||||
TASKS.lock().select(idx);
|
TASKS.lock().select(idx).unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+112
-114
@@ -1,117 +1,115 @@
|
|||||||
use async_trait::async_trait;
|
// use async_trait::async_trait;
|
||||||
use alloc::boxed::Box;
|
// use alloc::boxed::Box;
|
||||||
use alloc::string::String;
|
// use alloc::string::String;
|
||||||
use alloc::vec;
|
// use alloc::vec;
|
||||||
use alloc::vec::Vec;
|
// use alloc::vec::Vec;
|
||||||
use crate::std::frame::{ColouredChar};
|
// use crate::std::frame::{ColouredChar};
|
||||||
use crate::{serial_print, serial_println};
|
// use crate::{serial_print, serial_println};
|
||||||
use crate::std::application::{Application, Error};
|
// use crate::std::application::{Application, Error};
|
||||||
use crate::std::io::Screen;
|
// use crate::std::io::{Display, Screen};
|
||||||
use crate::user::lib::coords::{Direction, Position, PositionReal};
|
// use crate::user::lib::coords::{Direction, Position, PositionReal};
|
||||||
|
//
|
||||||
|
//
|
||||||
pub(crate) struct TetrisEngine {
|
// pub(crate) struct TetrisEngine {
|
||||||
score: u32,
|
// score: u32,
|
||||||
next: TetrisPiece,
|
// next: TetrisPiece,
|
||||||
completed_frame: [[ColouredChar; 80]; 25], // this frame does not contain falling blocks, only static ones
|
// completed_frame: [[ColouredChar; 80]; 25], // this frame does not contain falling blocks, only static ones
|
||||||
|
//
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
#[async_trait]
|
// #[async_trait]
|
||||||
impl Application for TetrisEngine {
|
// impl Application for TetrisEngine {
|
||||||
fn new() -> Self {
|
// fn new() -> Self {
|
||||||
Self {
|
// Self {
|
||||||
score: 0,
|
// score: 0,
|
||||||
next: TetrisPiece::new(PieceType::OPiece),
|
// next: TetrisPiece::new(PieceType::OPiece),
|
||||||
completed_frame: [[ColouredChar::null(); 80]; 25],
|
// completed_frame: [[ColouredChar::null(); 80]; 25],
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
async fn run(&mut self, args: Vec<String>) -> Result<(), Error> {
|
// async fn run(&mut self, args: Vec<String>) -> Result<(), Error> {
|
||||||
// setup:
|
// // setup:
|
||||||
Screen::Application.set_mode();
|
// let d = Display::borrow();
|
||||||
|
//
|
||||||
let piece_type = PieceType::OPiece;
|
// let piece_type = PieceType::OPiece;
|
||||||
let mut piece = TetrisPiece::new(piece_type);
|
// let mut piece = TetrisPiece::new(piece_type);
|
||||||
|
//
|
||||||
serial_println!("{:?}", piece.get_positions());
|
// serial_println!("{:?}", piece.get_positions());
|
||||||
piece.rotate_right();
|
// piece.rotate_right();
|
||||||
serial_println!("{:?}", piece.get_positions());
|
// serial_println!("{:?}", piece.get_positions());
|
||||||
|
//
|
||||||
|
// Ok(())
|
||||||
Screen::Terminal.set_mode();
|
// }
|
||||||
Ok(())
|
// }
|
||||||
}
|
//
|
||||||
}
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// enum PieceType {
|
||||||
|
// OPiece,
|
||||||
enum PieceType {
|
// IPiece,
|
||||||
OPiece,
|
// JPiece,
|
||||||
IPiece,
|
// LPiece,
|
||||||
JPiece,
|
// SPiece,
|
||||||
LPiece,
|
// ZPiece,
|
||||||
SPiece,
|
// }
|
||||||
ZPiece,
|
//
|
||||||
}
|
// struct TetrisPiece {
|
||||||
|
// type_: PieceType,
|
||||||
struct TetrisPiece {
|
// pos: Position,
|
||||||
type_: PieceType,
|
// rotation: Direction,
|
||||||
pos: Position,
|
// }
|
||||||
rotation: Direction,
|
//
|
||||||
}
|
// impl TetrisPiece {
|
||||||
|
// fn new(type_: PieceType) -> Self {
|
||||||
impl TetrisPiece {
|
// Self {
|
||||||
fn new(type_: PieceType) -> Self {
|
// type_,
|
||||||
Self {
|
// pos: Position { x: 40, y: 30 },
|
||||||
type_,
|
// rotation: Direction::Degrees0,
|
||||||
pos: Position { x: 40, y: 30 },
|
// }
|
||||||
rotation: Direction::Degrees0,
|
// }
|
||||||
}
|
// fn rotate_right(&mut self) {
|
||||||
}
|
// self.rotation = match self.rotation {
|
||||||
fn rotate_right(&mut self) {
|
// Direction::Degrees90 => Direction::Degrees180,
|
||||||
self.rotation = match self.rotation {
|
// Direction::Degrees180 => Direction::Degrees270,
|
||||||
Direction::Degrees90 => Direction::Degrees180,
|
// Direction::Degrees270 => Direction::Degrees0,
|
||||||
Direction::Degrees180 => Direction::Degrees270,
|
// Direction::Degrees0 => Direction::Degrees90,
|
||||||
Direction::Degrees270 => Direction::Degrees0,
|
// Direction::None => panic!("direction should never be none in this application"),
|
||||||
Direction::Degrees0 => Direction::Degrees90,
|
// };
|
||||||
Direction::None => panic!("direction should never be none in this application"),
|
// }
|
||||||
};
|
//
|
||||||
}
|
// /// function that maps the coordinates of the object.
|
||||||
|
// fn get_positions(&self) -> Vec<Position> {
|
||||||
/// function that maps the coordinates of the object.
|
// match self.type_ {
|
||||||
fn get_positions(&self) -> Vec<Position> {
|
// PieceType::OPiece => {
|
||||||
match self.type_ {
|
// let positions = vec![
|
||||||
PieceType::OPiece => {
|
// PositionReal { x: -0.5, y: -0.5 },
|
||||||
let positions = vec![
|
// PositionReal { x: 0.5, y: -0.5 },
|
||||||
PositionReal { x: -0.5, y: -0.5 },
|
// PositionReal { x: -0.5, y: 0.5 },
|
||||||
PositionReal { x: 0.5, y: -0.5 },
|
// PositionReal { x: 0.5, y: 0.5 },
|
||||||
PositionReal { x: -0.5, y: 0.5 },
|
// ];
|
||||||
PositionReal { x: 0.5, y: 0.5 },
|
// positions.into_iter().map(|p|
|
||||||
];
|
// ( p.rotate(self.rotation.clone()) + self.pos.clone().real() + PositionReal { x: -0.5, y: 0.5 } ).integer()
|
||||||
positions.into_iter().map(|p|
|
// ).collect::<Vec<Position>>()
|
||||||
( p.rotate(self.rotation.clone()) + self.pos.clone().real() + PositionReal { x: -0.5, y: 0.5 } ).integer()
|
// }
|
||||||
).collect::<Vec<Position>>()
|
// _ => unimplemented!("E"),
|
||||||
}
|
// }
|
||||||
_ => unimplemented!("E"),
|
// }
|
||||||
}
|
// }
|
||||||
}
|
//
|
||||||
}
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,13 +1,10 @@
|
|||||||
use hashbrown::HashMap;
|
use hashbrown::HashMap;
|
||||||
use spin::{Mutex, MutexGuard};
|
use spin::{Mutex};
|
||||||
use crate::{printerr, serial_println};
|
use crate::std::frame::{Frame, RenderError};
|
||||||
use crate::std::frame::{ColouredChar, Dimensions, Position, special_char, Frame, RenderError, ColorCode};
|
|
||||||
|
|
||||||
use alloc::{
|
use alloc::{
|
||||||
boxed::Box,
|
boxed::Box,
|
||||||
sync::Arc,
|
sync::Arc,
|
||||||
vec::Vec,
|
|
||||||
vec,
|
|
||||||
string::String,
|
string::String,
|
||||||
};
|
};
|
||||||
use core::any::Any;
|
use core::any::Any;
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ use alloc::string::String;
|
|||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
use alloc::boxed::Box;
|
use alloc::boxed::Box;
|
||||||
use core::any::Any;
|
use core::any::Any;
|
||||||
use core::task::ready;
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use crate::std::application::Exit;
|
use crate::std::application::Exit;
|
||||||
use crate::std::frame::{ColouredChar, Dimensions, Frame, Position, RenderError};
|
use crate::std::frame::{ColouredChar, Dimensions, Frame, Position, RenderError};
|
||||||
@@ -23,7 +22,7 @@ impl CgLineEdit {
|
|||||||
CgLineEdit {
|
CgLineEdit {
|
||||||
position,
|
position,
|
||||||
dimensions: Dimensions::new(width, 1),
|
dimensions: Dimensions::new(width, 1),
|
||||||
prompt: prompt,
|
prompt,
|
||||||
text: Vec::new(),
|
text: Vec::new(),
|
||||||
ptr: 0
|
ptr: 0
|
||||||
}
|
}
|
||||||
@@ -39,24 +38,24 @@ impl CgComponent for CgLineEdit {
|
|||||||
if idx >= self.dimensions.x {
|
if idx >= self.dimensions.x {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
frame.write(Position::new(idx, 0), ColouredChar::new(c));
|
frame.write(Position::new(idx, 0), ColouredChar::new(c)).unwrap();
|
||||||
idx += 1
|
idx += 1
|
||||||
}
|
}
|
||||||
|
|
||||||
idx += 1; // create a space between the prompt and the text
|
idx += 1; // create a space between the prompt and the text
|
||||||
|
|
||||||
if idx + self.text.len() > self.dimensions.x {
|
if idx + self.text.len() > self.dimensions.x {
|
||||||
frame.write(Position::new(idx, 0), ColouredChar::new('['));
|
frame.write(Position::new(idx, 0), ColouredChar::new('[')).unwrap();
|
||||||
frame.write(Position::new(idx + 1, 0), ColouredChar::new('.'));
|
frame.write(Position::new(idx + 1, 0), ColouredChar::new('.')).unwrap();
|
||||||
frame.write(Position::new(idx + 2, 0), ColouredChar::new('.'));
|
frame.write(Position::new(idx + 2, 0), ColouredChar::new('.')).unwrap();
|
||||||
frame.write(Position::new(idx + 3, 0), ColouredChar::new('.'));
|
frame.write(Position::new(idx + 3, 0), ColouredChar::new('.')).unwrap();
|
||||||
frame.write(Position::new(idx + 4, 0), ColouredChar::new(']'));
|
frame.write(Position::new(idx + 4, 0), ColouredChar::new(']')).unwrap();
|
||||||
idx += 5
|
idx += 5
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
self.text.iter().rev().take(self.dimensions.x - idx).rev().for_each(|c| {
|
self.text.iter().rev().take(self.dimensions.x - idx).rev().for_each(|c| {
|
||||||
frame.write(Position::new(idx, 0), ColouredChar::new(*c));
|
frame.write(Position::new(idx, 0), ColouredChar::new(*c)).unwrap();
|
||||||
idx += 1
|
idx += 1
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,21 +1,23 @@
|
|||||||
use crate::std::frame::{ColouredChar, Dimensions, Frame, Position};
|
use crate::std::frame::{ColouredChar, Dimensions, Frame, Position, RenderError};
|
||||||
|
|
||||||
pub(crate) fn render_outline(frame: &mut Frame, dimensions: Dimensions) {
|
pub(crate) fn render_outline(frame: &mut Frame, dimensions: Dimensions) -> Result<(), RenderError> {
|
||||||
// draws the sides of the container
|
// draws the sides of the container
|
||||||
for i in 0..frame.dimensions.x {
|
for i in 0..frame.dimensions.x {
|
||||||
frame.write(Position::new(i, 0), ColouredChar::new('─'));
|
frame.write(Position::new(i, 0), ColouredChar::new('─'))?;
|
||||||
frame.write(Position::new(i, frame.dimensions.y - 1), ColouredChar::new('─'));
|
frame.write(Position::new(i, frame.dimensions.y - 1), ColouredChar::new('─'))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// draws the top and bottom of the container
|
// draws the top and bottom of the container
|
||||||
for i in 0..frame.dimensions.y {
|
for i in 0..frame.dimensions.y {
|
||||||
frame.write(Position::new(0, i), ColouredChar::new('│'));
|
frame.write(Position::new(0, i), ColouredChar::new('│'))?;
|
||||||
frame.write(Position::new(frame.dimensions.x - 1, i), ColouredChar::new('│'));
|
frame.write(Position::new(frame.dimensions.x - 1, i), ColouredChar::new('│'))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// draws the corners of the container
|
// draws the corners of the container
|
||||||
frame.write(Position::new(0, 0), ColouredChar::new('┌'));
|
frame.write(Position::new(0, 0), ColouredChar::new('┌'))?;
|
||||||
frame.write(Position::new(dimensions.x - 1, 0), ColouredChar::new('┐'));
|
frame.write(Position::new(dimensions.x - 1, 0), ColouredChar::new('┐'))?;
|
||||||
frame.write(Position::new(0, dimensions.y - 1), ColouredChar::new('└'));
|
frame.write(Position::new(0, dimensions.y - 1), ColouredChar::new('└'))?;
|
||||||
frame.write(Position::new(dimensions.x - 1, dimensions.y - 1), ColouredChar::new('┘'));
|
frame.write(Position::new(dimensions.x - 1, dimensions.y - 1), ColouredChar::new('┘'))?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,11 @@
|
|||||||
use alloc::{boxed::Box, format, string::String, vec, vec::Vec};
|
use alloc::{boxed::Box, format, string::String, vec::Vec};
|
||||||
use alloc::fmt::format;
|
|
||||||
use alloc::string::ToString;
|
use alloc::string::ToString;
|
||||||
use core::any::Any;
|
use core::any::Any;
|
||||||
use core::cmp::{max, min};
|
use core::cmp::{max, min};
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use hashbrown::HashMap;
|
use hashbrown::HashMap;
|
||||||
use crate::serial_println;
|
|
||||||
use crate::std::application::Exit;
|
use crate::std::application::Exit;
|
||||||
use super::cg_core::{CgComponent, CgKeyboardCapture, CgOutline, Widget};
|
use super::cg_core::{CgComponent, CgKeyboardCapture, Widget};
|
||||||
use super::cg_utils::render_outline;
|
use super::cg_utils::render_outline;
|
||||||
use crate::std::frame::{ColouredChar, Dimensions, Position, Frame, RenderError, ColorCode, BUFFER_WIDTH, BUFFER_HEIGHT};
|
use crate::std::frame::{ColouredChar, Dimensions, Position, Frame, RenderError, ColorCode, BUFFER_WIDTH, BUFFER_HEIGHT};
|
||||||
use crate::std::io::{Color, KeyStroke, Stdin};
|
use crate::std::io::{Color, KeyStroke, Stdin};
|
||||||
@@ -48,7 +46,7 @@ impl CgComponent for CgContainer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if self.outlined {
|
if self.outlined {
|
||||||
render_outline(&mut result, self.dimensions.clone());
|
render_outline(&mut result, self.dimensions.clone())?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(result)
|
Ok(result)
|
||||||
@@ -73,17 +71,18 @@ impl CgTextBox {
|
|||||||
CgTextBox { title, content, position, dimensions, outlined, wrap_words: true }
|
CgTextBox { title, content, position, dimensions, outlined, wrap_words: true }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_title(&self, frame: &mut Frame) {
|
fn render_title(&self, frame: &mut Frame) -> Result<(), RenderError>{
|
||||||
let title = self.title.chars();
|
let title = self.title.chars();
|
||||||
for (i, c) in title.enumerate() {
|
for (i, c) in title.enumerate() {
|
||||||
if i + 2 == self.dimensions.x - 3 { // we don't want to write at the top of the text box
|
if i + 2 == self.dimensions.x - 3 { // we don't want to write at the top of the text box
|
||||||
frame.write(Position::new(i + 1, 0), ColouredChar::new('.'));
|
frame.write(Position::new(i + 1, 0), ColouredChar::new('.'))?;
|
||||||
} else if i + 2 >= self.dimensions.x - 2 {
|
} else if i + 2 >= self.dimensions.x - 2 {
|
||||||
frame.write(Position::new(i + 1, 0), ColouredChar::new('.'));
|
frame.write(Position::new(i + 1, 0), ColouredChar::new('.'))?;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
frame.write(Position::new(i + 2, 0), ColouredChar::new(c));
|
frame.write(Position::new(i + 2, 0), ColouredChar::new(c))?;
|
||||||
}
|
};
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
pub fn wrap_words(&mut self, wrap: bool) {
|
pub fn wrap_words(&mut self, wrap: bool) {
|
||||||
self.wrap_words = wrap;
|
self.wrap_words = wrap;
|
||||||
@@ -95,10 +94,10 @@ impl CgComponent for CgTextBox {
|
|||||||
let mut result = Frame::new(self.position, self.dimensions)?;
|
let mut result = Frame::new(self.position, self.dimensions)?;
|
||||||
|
|
||||||
if self.outlined {
|
if self.outlined {
|
||||||
render_outline(&mut result, self.dimensions.clone());
|
render_outline(&mut result, self.dimensions.clone())?;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.render_title(&mut result);
|
self.render_title(&mut result)?;
|
||||||
|
|
||||||
let (mut x, mut y) = (1, 1);
|
let (mut x, mut y) = (1, 1);
|
||||||
|
|
||||||
@@ -123,13 +122,13 @@ impl CgComponent for CgTextBox {
|
|||||||
if y == self.dimensions.y - 1 {
|
if y == self.dimensions.y - 1 {
|
||||||
if c != ' ' {
|
if c != ' ' {
|
||||||
(2..5).for_each(|z| {
|
(2..5).for_each(|z| {
|
||||||
result.write(Position::new(self.dimensions.x - z, self.dimensions.y - 1), ColouredChar::new('.'));
|
result.write(Position::new(self.dimensions.x - z, self.dimensions.y - 1), ColouredChar::new('.')).unwrap();
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
result.write(Position::new(x, y), ColouredChar::new(c));
|
result.write(Position::new(x, y), ColouredChar::new(c))?;
|
||||||
x += 1;
|
x += 1;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -180,11 +179,11 @@ impl CgComponent for CgLabel {
|
|||||||
for (i, c) in shortened_string.chars().enumerate() {
|
for (i, c) in shortened_string.chars().enumerate() {
|
||||||
if i + left >= self.dimensions.x {
|
if i + left >= self.dimensions.x {
|
||||||
(0..3).for_each(|z| {
|
(0..3).for_each(|z| {
|
||||||
result.write(Position::new(self.dimensions.x - z + left, self.dimensions.y - 1), ColouredChar::new('.'));
|
result.write(Position::new(self.dimensions.x - z + left, self.dimensions.y - 1), ColouredChar::new('.')).expect("failed to write");
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
result.write(Position::new(i + left, 0), ColouredChar::new(c));
|
result.write(Position::new(i + left, 0), ColouredChar::new(c))?;
|
||||||
};
|
};
|
||||||
Ok(result)
|
Ok(result)
|
||||||
}
|
}
|
||||||
@@ -235,7 +234,7 @@ impl CgComponent for CgIndicatorWidget {
|
|||||||
|
|
||||||
let shortened_string = self.content.chars().take(self.max_width).collect::<String>();
|
let shortened_string = self.content.chars().take(self.max_width).collect::<String>();
|
||||||
for (i, c) in shortened_string.chars().enumerate() {
|
for (i, c) in shortened_string.chars().enumerate() {
|
||||||
result.write(Position::new(i, 0), ColouredChar::coloured(c, self.colour));
|
result.write(Position::new(i, 0), ColouredChar::coloured(c, self.colour)).expect("failed to render indicator widget");
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(result)
|
Ok(result)
|
||||||
@@ -419,7 +418,9 @@ impl CgComponent for CgDialog {
|
|||||||
|
|
||||||
// now that we know the X and Y offsets, we can start to draw the frame
|
// now that we know the X and Y offsets, we can start to draw the frame
|
||||||
let mut frame = Frame::new(Position::new(x_offset, y_offset), Dimensions::new(width, height))?;
|
let mut frame = Frame::new(Position::new(x_offset, y_offset), Dimensions::new(width, height))?;
|
||||||
render_outline(&mut frame, Dimensions::new(width, height));
|
if let Err(e) = render_outline(&mut frame, Dimensions::new(width, height)) {
|
||||||
|
return Err(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// render title
|
// render title
|
||||||
@@ -449,7 +450,7 @@ impl CgComponent for CgDialog {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
frame.write(Position::new(x, y), ColouredChar::new(c));
|
frame.write(Position::new(x, y), ColouredChar::new(c)).unwrap();
|
||||||
x += 1;
|
x += 1;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -462,7 +463,7 @@ impl CgComponent for CgDialog {
|
|||||||
frame.write(Position::new(button_x_offset + i, height - 3), ColouredChar {
|
frame.write(Position::new(button_x_offset + i, height - 3), ColouredChar {
|
||||||
character: c,
|
character: c,
|
||||||
colour: ColorCode::new(Color::Cyan, Color::Black),
|
colour: ColorCode::new(Color::Cyan, Color::Black),
|
||||||
});
|
}).expect("failed to write to frame, perhaps buttons were placed wrongly or width too great");
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
CgDialogType::Confirmation => {
|
CgDialogType::Confirmation => {
|
||||||
@@ -483,7 +484,7 @@ impl CgComponent for CgDialog {
|
|||||||
|
|
||||||
let button_x_offset = (width - button_fmt.len()) / 2;
|
let button_x_offset = (width - button_fmt.len()) / 2;
|
||||||
button_fmt.into_iter().enumerate().for_each(|(i, c)| {
|
button_fmt.into_iter().enumerate().for_each(|(i, c)| {
|
||||||
frame.write(Position::new(button_x_offset + i, height - 3), c);
|
frame.write(Position::new(button_x_offset + i, height - 3), c).expect("failed to write to frame, perhaps buttons were placed wrongly or width too great");
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
CgDialogType::Selection(options) => {
|
CgDialogType::Selection(options) => {
|
||||||
@@ -504,7 +505,7 @@ impl CgComponent for CgDialog {
|
|||||||
|
|
||||||
let button_x_offset = (width - button_fmt.len()) / 2;
|
let button_x_offset = (width - button_fmt.len()) / 2;
|
||||||
button_fmt.into_iter().enumerate().for_each(|(i, c)| {
|
button_fmt.into_iter().enumerate().for_each(|(i, c)| {
|
||||||
frame.write(Position::new(button_x_offset + i, height - 3), c);
|
frame.write(Position::new(button_x_offset + i, height - 3), c).expect("failed to write to frame, perhaps buttons were placed wrongly or width too great");
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user