use std::io::{stdout, Result}; /* use emmaemu::{chip8::{computer::Chip8Computer, video::Chip8Video}, constants::{CHIP8_MEMORY_SIZE, CHIP8_REGISTER_COUNT, CHIP8_ROM_SIZE, CHIP8_VIDEO_MEMORY}}; use ratatui::{ backend::CrosstermBackend, crossterm::{ event::{self, KeyCode, KeyEventKind}, terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen}, ExecutableCommand, }, layout::{Alignment, Rect}, style::{Style, Stylize}, widgets::{List, Paragraph, Widget}, Frame, Terminal, }; fn system_memory_to_text_render(data_to_dump: [u8; 2048]) -> String { let mut to_return = String::new(); for i in 0..256 { to_return += &format!("{:x}\t", data_to_dump[i as usize]).to_string(); if ((i + 1) % CHIP8_REGISTER_COUNT) == 0 { to_return += "\n"; } } to_return } fn dump_memory_to_console(data_to_dump: [u8; 2048]) { println!("STARTING TO DUMP MEMORY TO CONSOLE"); println!("{}", system_memory_to_text_render(data_to_dump)); println!("DONE DUMPING!"); panic!("DONE DUMPING"); } struct ControlKeyboard { } impl Widget for ControlKeyboard { fn render(self, area: Rect, buf: &mut ratatui::prelude::Buffer) where Self: Sized { let style = Style::new(); buf.set_string(0, 0, "F1 to cycle foreground - F2 to cycle background", style) } } #[derive(Clone)] struct AppState { pub menu_items: Vec, pub selected_menu_item: i32, pub system: Chip8Computer, } impl Default for AppState { fn default() -> Self { println!("Creating new AppState"); Self { menu_items: vec![ "Step CPU ".into(), "Reset CPU ".into(), "Item 3".into(), ], selected_menu_item: 0, system: Chip8Computer { ..Default::default() }, } } } fn main() -> Result<()> { stdout().execute(EnterAlternateScreen)?; enable_raw_mode()?; let mut terminal = Terminal::new(CrosstermBackend::new(stdout()))?; terminal.clear()?; let app = AppState::default(); loop { // Draw Ui... terminal.draw(|frame| { frame.render_widget(app.system.memory, frame.area()); // frame.render_widget(app.control_keyboard, area); //render_cpu_state(app.system.clone(), frame); // render_video_state(app.system.video_memory, frame); // render_menu_list(app.clone(), frame); })?; // ...handle Events. if event::poll(std::time::Duration::from_millis(16))? { if let event::Event::Key(key) = event::read()? { match key.kind { KeyEventKind::Press => match key.code { KeyCode::F(5) => { println!("Execute Next Instruction"); } KeyCode::F(12) => { println!("Resetting CPU"); } KeyCode::Char('q') => { break; } _ => (), }, _ => (), } } } } // stdout().execute(LeaveAlternateScreen)?; // disable_raw_mode()?; Ok(()) } #[cfg(test)] mod test { use emmaemu::constants::{CHIP8_VIDEO_HEIGHT, CHIP8_VIDEO_WIDTH}; use crate::*; #[test] fn blank_screen_renders_to_text() { let test_video = Chip8Video::default(); let blank_data: [bool; CHIP8_VIDEO_MEMORY] = [false; CHIP8_VIDEO_MEMORY]; let blank_screen = (" ".repeat(CHIP8_VIDEO_WIDTH.try_into().unwrap()) + "\n") .repeat(CHIP8_VIDEO_HEIGHT.try_into().unwrap()); assert_eq!(Chip8Video::new(blank_data).format_as_string(), blank_screen); } #[test] fn filled_screen_renders_to_text() { let filled_data: [bool; CHIP8_VIDEO_MEMORY] = [true; CHIP8_VIDEO_MEMORY]; let filled_screen = ("*".repeat(CHIP8_VIDEO_WIDTH.try_into().unwrap()) + "\n") .repeat(CHIP8_VIDEO_HEIGHT.try_into().unwrap()); assert_eq!(Chip8Video::new(filled_data).format_as_string(), filled_screen); } #[test] fn grid_pattern_renders_to_text() { let mut grid_data: [bool; CHIP8_VIDEO_MEMORY] = [false; CHIP8_VIDEO_MEMORY]; let mut expected_data = String::new(); for i in 0..CHIP8_VIDEO_MEMORY { grid_data[i] = (i % 2 == 0); if i % 2 == 0 { grid_data[i] = true; expected_data += "*"; } else { grid_data[i] = false; expected_data += " "; } if (i as i32 % CHIP8_VIDEO_WIDTH as i32 == CHIP8_VIDEO_WIDTH - 1) { expected_data += "\n"; } } assert_eq!(Chip8Video::new(grid_data).format_as_string(), expected_data); } } */ fn main() { println!("Taxation is theft"); }