use crsn::asm::data::Rd; use crsn::asm::error::CrsnError; use crsn::asm::instr::op::OpKind; use crsn::asm::parse::arg_parser::TokenParser; use crsn::module::ParseRes; use crsn::sexp::SourcePosition; use crate::defs::ScreenOp; use super::exec::OPT_AUTO_BLIT; use super::exec::OPT_FRAME_RATE; use super::exec::OPT_UPSCALE; pub(crate) fn parse<'a>(_pos: &SourcePosition, keyword: &str, mut args: TokenParser<'a>) -> Result, CrsnError> { let rv = Ok(ParseRes::ext(match keyword { "sc-init" => { ScreenOp::ScreenInit { width: args.next_rd()?, height: args.next_rd()?, } } "sc-erase" => { ScreenOp::Erase { color: if args.len() > 0 { args.next_rd()? } else { Rd::new_imm(0) // black }, } } "sc-wr" | "sc-px" => { ScreenOp::SetPixel { x: args.next_rd()?, y: args.next_rd()?, color: args.next_rd()?, } } "sc-rd" => { ScreenOp::GetPixel { color: args.next_wr()?, x: args.next_rd()?, y: args.next_rd()?, } } "sc-opt" => { let (val, valopt) = args.next_value()?; ScreenOp::SetOpt { opt: match val { OPT_AUTO_BLIT => { OPT_AUTO_BLIT // TODO use enum } OPT_FRAME_RATE => { OPT_FRAME_RATE } OPT_UPSCALE => { OPT_UPSCALE } _ => { return Err(CrsnError::Parse("Bad screen option".into(), valopt)); } }, val: args.next_rd()?, } } "sc-blit" => { ScreenOp::Blit { force: if args.have_more() { args.next_rd()? } else { Rd::new_imm(1) }, } } "sc-poll" => { ScreenOp::Update } "sc-mouse" => { ScreenOp::GetMouse { x: args.next_wr()?, y: args.next_wr()?, } } "sc-key" => { ScreenOp::TestKey { pressed: args.next_wr()?, code: args.next_rd()?, } } "sc-mbtn" => { ScreenOp::TestMouse { pressed: args.next_wr()?, button: args.next_rd()?, } } "sc-rect" => { ScreenOp::FillRect { x: args.next_rd()?, y: args.next_rd()?, w: args.next_rd()?, h: args.next_rd()?, color: args.next_rd()? } } _other => { return Ok(ParseRes::Unknown(args)); } })); args.ensure_empty_custom("Too many arguments for this instruction!")?; return rv; }