diff --git a/src/cli.rs b/src/cli.rs new file mode 100644 index 0000000..c3796cb --- /dev/null +++ b/src/cli.rs @@ -0,0 +1,121 @@ +use std::{ + env, + fs::File, + io::{ErrorKind, Read}, + process::exit, +}; + +use serde::{Deserialize, Serialize}; + +use crate::memory::Mem; + +#[derive(Serialize, Deserialize, Debug)] +struct Config { + char_rom: Option, + rom: String, +} + +pub fn get_input(memory: &mut Mem) { + let args: Vec = env::args().collect(); + + match args.len() { + 0 => { + println!("george-emu must be run in the terminal, don't know what went wrong here!"); + exit(1) + } + 1 => { + let config: Config = match File::open("./george.toml") { + Ok(mut file) => { + let mut string = String::new(); + file.read_to_string(&mut string).unwrap(); + toml::from_str(string.as_str()).unwrap() + } + Err(_) => { + println!("couldn't find a `george.toml` in the current directory!"); + exit(1); + } + }; + let rom = match std::fs::File::open(config.rom) { + Ok(file) => file, + Err(error) => panic!("Couldn't open main rom! {:?}", error), + }; + if let Err(error) = memory.load_rom(rom) { + println!("{:?}", error); + }; + } + 2 => match &args[1] as &str { + "help" => { + println!("ʕ·ᴥ·ʔ- george-emu is an emulator for george:"); + println!("https://git.augustkline.com/august/george\n"); + println!("commands:"); + println!(" help: print this help screen"); + println!(" help : print help info for any command"); + println!(" rom : load a rom/binary from path\n"); + println!("configuration:"); + println!(" george-emu searches for a `george.toml` in the current directory. in `george.toml` you can specify a path for the character rom using the key `char_rom` and the main rom/binary with the key `rom`"); + exit(0); + } + _ => { + println!( + "{:?} isn't a valid command!\n\nuse `{} help` to see all valid commands", + &args[1], &args[0] + ); + exit(1); + } + }, + 3 => match &args[1] as &str { + "help" => match &args[2] as &str { + "rom" => { + println!("{:?} rom \nload a rom/binary from path", &args[0]); + } + _ => { + println!( + "{:?} isn't a valid command!\n\nuse `{} help` to see all valid commands", + &args[2], &args[0] + ); + exit(1); + } + }, + "rom" => { + let rom = match std::fs::File::open(&args[2]) { + Ok(file) => file, + Err(error) => { + match error.kind() { + ErrorKind::NotFound => { + println!("couldn't find the rom at {:?}", &args[2]); + } + ErrorKind::PermissionDenied => { + println!( + "didn't have sufficient permissions to open the rom at {:?}", + &args[2] + ); + } + _ => { + println!("something went wrong! try again in a moment? really not sure why you're getting this error"); + } + } + exit(1); + } + }; + if let Err(error) = memory.load_rom(rom) { + println!("oh no! this rom couldn't be loaded: {:?}", error); + exit(1); + }; + } + _ => { + println!( + "{:?} isn't a valid command!\n\nuse `{} help` to see all valid commands", + &args[1], &args[0] + ); + exit(1); + } + }, + _ => { + println!( + "too many arguments were provided!\n\nuse `{} help` to see all valid commands", + &args[0] + ); + exit(1); + } + } +} diff --git a/src/main.rs b/src/main.rs index b42b3a7..d2718a1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,4 @@ -// #![allow(dead_code)] - +mod cli; mod cpu; mod error; mod instructions; @@ -13,24 +12,15 @@ 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 serde::{Deserialize, Serialize}; - -use std::env; -use std::io::ErrorKind; -use std::process::exit; +use std::io::{stdout, Result}; use std::thread::{self, sleep}; use std::time::Duration; -use std::{ - fs::File, - io::{stdout, Read, Result}, - path::PathBuf, - str::FromStr, -}; use crossterm::{ cursor, @@ -38,159 +28,51 @@ use crossterm::{ terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen}, }; -#[derive(Serialize, Deserialize, Debug)] -struct Config { - char_rom: Option, - rom: String, -} +// 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 args: Vec = env::args().collect(); - - let mut memory = Mem::new(); - match args.len() { - 0 => { - println!("george-emu must be run in the terminal, don't know what went wrong here!"); - exit(1) - } - 1 => { - let config: Config = match File::open("./george.toml") { - Ok(mut file) => { - let mut string = String::new(); - file.read_to_string(&mut string).unwrap(); - toml::from_str(string.as_str()).unwrap() - } - Err(_) => { - println!("couldn't find a `george.toml` in the current directory!"); - exit(1); - } - }; - let rom = match std::fs::File::open(config.rom) { - Ok(file) => file, - Err(error) => panic!("Couldn't open main rom! {:?}", error), - }; - if let Err(error) = memory.load_rom(rom) { - println!("{:?}", error); - }; - } - 2 => match &args[1] as &str { - "help" => { - println!("ʕ·ᴥ·ʔ- george-emu is an emulator for george:"); - println!("https://git.augustkline.com/august/george\n"); - println!("commands:"); - println!(" help: print this help screen"); - println!(" help : print help info for any command"); - println!(" rom : load a rom/binary from path\n"); - println!("configuration:"); - println!(" george-emu searches for a `george.toml` in the current directory. in `george.toml` you can specify a path for the character rom using the key `char_rom` and the main rom/binary with the key `rom`"); - exit(0); - } - _ => { - println!( - "{:?} isn't a valid command!\n\nuse `{} help` to see all valid commands", - &args[1], &args[0] - ); - exit(1); - } - }, - 3 => match &args[1] as &str { - "help" => match &args[2] as &str { - "rom" => { - println!("{:?} rom \nload a rom/binary from path", &args[0]); - } - _ => { - println!( - "{:?} isn't a valid command!\n\nuse `{} help` to see all valid commands", - &args[2], &args[0] - ); - exit(1); - } - }, - "rom" => { - let rom = match std::fs::File::open(&args[2]) { - Ok(file) => file, - Err(error) => { - match error.kind() { - ErrorKind::NotFound => { - println!("couldn't find the rom at {:?}", &args[2]); - } - ErrorKind::PermissionDenied => { - println!( - "didn't have sufficient permissions to open the rom at {:?}", - &args[2] - ); - } - _ => { - println!("something went wrong! try again in a moment? really not sure why you're getting this error"); - } - } - exit(1); - } - }; - if let Err(error) = memory.load_rom(rom) { - println!("oh no! this rom couldn't be loaded: {:?}", error); - exit(1); - }; - } - _ => { - println!( - "{:?} isn't a valid command!\n\nuse `{} help` to see all valid commands", - &args[1], &args[0] - ); - exit(1); - } - }, - _ => { - println!( - "too many arguments were provided!\n\nuse `{} help` to see all valid commands", - &args[0] - ); - exit(1); - } - } 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()?; - memory - .dump(PathBuf::from_str("./coredump.bin").unwrap()) - .unwrap(); - let shared_memory = MemHandle::new(memory); let screen_memory = shared_memory.clone(); let cpu_memory = shared_memory.clone(); let keyboard_memory = shared_memory.clone(); - // 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(); - let keyboard = Keyboard::new(keyboard_memory); let (mut cpu, cpu_controller) = Cpu::new_with_control(cpu_memory);