use structopt::StructOpt;
use std::path::PathBuf;
use tinychip::{
emulator::EmulatorBuilder,
apis::api::{
ApiKind,
RECTS_X,
RECTS_Y
},
interpreters::types::InterpreterType,
models::{
core::Core,
interpreter::Interpreter
},
error::ChipError
};
#[derive(StructOpt, Debug)]
#[structopt(name = "tinychip")]
struct Opt {
#[structopt(parse(from_os_str))]
rom: PathBuf,
#[structopt(short, long)]
width: Option<u32>,
#[structopt(short, long)]
height: Option<u32>,
#[structopt(long)]
api: Option<ApiKind>,
#[structopt(long)]
interpreter: Option<InterpreterType>,
#[structopt(long)]
cycles: Option<u64>,
#[structopt(long)]
original_load: Option<bool>,
#[structopt(long)]
original_shift: Option<bool>
}
impl Opt {
pub fn width(&self) -> u32 {
self.width.unwrap_or(RECTS_X * 20)
}
pub fn height(&self) -> u32 {
self.height.unwrap_or(RECTS_Y * 20)
}
pub fn size(&self) -> (u32, u32) {
(self.width(), self.height())
}
pub fn api(&self) -> ApiKind {
self.api.unwrap_or_default()
}
pub fn interpreter(&self) -> Box<dyn Interpreter> {
self.interpreter.unwrap_or_default().into()
}
pub fn cycles(&self) -> u64 {
let ret = self.cycles.unwrap_or(500);
if ret <= 500 {
500
} else if ret > 2000 {
2000
} else {
ret
}
}
pub fn original_load(&self) -> bool {
self.original_load.unwrap_or(false)
}
pub fn original_shift(&self) -> bool {
self.original_shift.unwrap_or(false)
}
}
fn main() -> Result<(), ChipError> {
let args = Opt::from_args();
let mut interpreter = args.interpreter();
interpreter.set_original_load(args.original_load());
interpreter.set_original_shift(args.original_shift());
let mut emu = EmulatorBuilder::new()
.set_api(args.api())
.set_window_size(args.size())
.set_window_title("tinychip")
.set_interpreter(interpreter)
.set_clock(args.cycles())
.build();
emu.load_from_file(args.rom)?;
emu.run();
Ok(())
}