mod cli; mod cpu; mod error; mod instructions; mod keyboard; mod memory; mod types; mod video; use crate::cpu::Cpu; use crate::keyboard::Keyboard; use crate::memory::Mem; use crate::video::{Screen, TerminalRenderer}; use cli::get_input; use crossterm::execute; use crossterm::terminal::{size, Clear, ClearType, SetSize}; // use cpu::CpuController; use memory::MemHandle; // use minifb::{Scale, ScaleMode, Window, WindowOptions}; use std::io::{stdout, Result}; use std::thread::{self, sleep}; use std::time::Duration; use crossterm::{ cursor, event::{self, KeyCode, KeyEventKind}, terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen}, }; // For when we want to leave the terminal again :sigh: // // thread::spawn(move || { // let mut screen = Crtc::new( // screen_memory, // config.char_rom.as_ref(), // CpuController::new(screen_cpu_tx), // window_tx, // ); // screen.run(); // }); // let mut window = Window::new( // "ʕ·ᴥ·ʔ-☆", // 512, // 380, // WindowOptions { // resize: true, // borderless: true, // title: true, // transparency: false, // scale: Scale::X2, // scale_mode: ScaleMode::AspectRatioStretch, // topmost: false, // none: true, // }, // ) // .unwrap(); fn main() -> Result<()> { let mut stdout = stdout(); let (cols, rows) = size()?; let mut memory = Mem::new(); get_input(&mut memory); execute!(stdout, SetSize(64, 29), cursor::Hide, EnterAlternateScreen)?; enable_raw_mode()?; let shared_memory = MemHandle::new(memory); let screen_memory = shared_memory.clone(); let cpu_memory = shared_memory.clone(); let keyboard_memory = shared_memory.clone(); let keyboard = Keyboard::new(keyboard_memory); let (mut cpu, cpu_controller) = Cpu::new_with_control(cpu_memory); let _ = cpu.reset(); thread::spawn(move || loop { cpu.cycle(); }); let stdout_lock = stdout.lock(); let renderer = TerminalRenderer::new(screen_memory, stdout_lock); let mut screen = Screen::new(renderer, cpu_controller); loop { sleep(Duration::from_millis(16)); screen.draw(); if event::poll(std::time::Duration::from_millis(16))? { if let event::Event::Key(key) = event::read()? { keyboard.read_keys(key); if key.kind == KeyEventKind::Press && key.code == KeyCode::Char('q') { break; } } } } execute!( stdout, LeaveAlternateScreen, SetSize(cols, rows), Clear(ClearType::Purge) )?; disable_raw_mode()?; Ok(()) }