mouse and key input, handle close btn, mouse demo

pull/21/head
Ondřej Hruška 4 years ago
parent 6eef2b7ae3
commit 583ac7bcbf
Signed by: MightyPork
GPG Key ID: 2C5FD5035250423D
  1. 2
      crsn/src/asm/instr/flatten.rs
  2. 2
      crsn/src/asm/instr/mod.rs
  3. 2
      crsn/src/asm/mod.rs
  4. 18
      crsn_screen/src/defs.rs
  5. 251
      crsn_screen/src/exec.rs
  6. 37
      crsn_screen/src/parse.rs
  7. 40
      examples/mouse.csn

@ -73,7 +73,7 @@ impl Flatten for Vec<Box<dyn Flatten>> {
for item in self.into_iter() {
ops.extend(item.flatten(label_num)?);
}
labels_to_skips(ops)
Ok(ops)
}
}

@ -6,7 +6,7 @@ use crate::asm::data::literal::RoutineName;
pub mod op;
pub mod cond;
mod flatten;
pub mod flatten;
/// A higher-level instruction
#[derive(Debug)]

@ -4,6 +4,7 @@ use std::sync::Arc;
use crate::asm::parse::{ParserContext, ParserState};
use crate::module::CrsnExtension;
use crate::runtime::program::Program;
use crate::asm::instr::flatten::labels_to_skips;
pub mod data;
pub mod error;
@ -23,6 +24,7 @@ pub fn assemble(source: &str, parsers: Arc<Vec<Box<dyn CrsnExtension>>>) -> Resu
};
let ops = parse::parse(source, &pcx)?;
let ops = labels_to_skips(ops)?;
Ok(Program::new(ops, parsers)?)
}

@ -1,4 +1,4 @@
use crsn::asm::data::Rd;
use crsn::asm::data::{Rd, Wr};
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum ScreenOp {
@ -11,6 +11,22 @@ pub enum ScreenOp {
y: Rd,
color: Rd,
},
GetMouse {
x: Wr,
y: Wr,
},
TestKey {
pressed: Wr,
code: Rd,
},
TestMouse {
pressed: Wr,
button: Rd,
},
Update,
Erase {
color: Rd,
},
Blit {
force: Rd,
},

@ -1,7 +1,7 @@
use std::ops::Sub;
use std::time::{Duration, Instant};
use minifb::{ScaleMode, Window, WindowOptions};
use minifb::{ScaleMode, Window, WindowOptions, MouseMode, Key, MouseButton};
use crsn::asm::data::literal::Value;
use crsn::asm::instr::Cond;
@ -61,7 +61,17 @@ impl OpTrait for ScreenOp {
let h = state.read(*height)?;
init(state, w, h)?;
}
ScreenOp::Erase { color } => {
let color = (state.read(*color)? & 0xffffff) as u32;
let backend: &mut Backend = state.ext_mut();
for n in 0..(backend.buffer.len()) {
backend.buffer[n] = color;
}
}
ScreenOp::SetOpt { opt, val } => {
state.clear_status();
let opt = state.read(*opt)?;
let val = state.read(*val)?;
let backend: &mut Backend = state.ext_mut();
@ -81,6 +91,7 @@ impl OpTrait for ScreenOp {
}
}
}
ScreenOp::Blit { force } => {
let force = state.read(*force)?;
let backend: &mut Backend = state.ext_mut();
@ -91,7 +102,21 @@ impl OpTrait for ScreenOp {
blit_maybe(backend)
}
}
ScreenOp::Update => {
let backend: &mut Backend = state.ext_mut();
match &mut backend.window {
Some(w) => {
w.update();
}
None => {
state.set_flag(Cond::Invalid, true);
}
}
}
ScreenOp::SetPixel { x, y, color } => {
state.clear_status();
let x = state.read(*x)?;
let y = state.read(*y)?;
let color = state.read(*color)?;
@ -122,6 +147,83 @@ impl OpTrait for ScreenOp {
}
}
}
ScreenOp::GetMouse { x, y } => {
state.clear_status();
let backend: &mut Backend = state.ext_mut();
match &mut backend.window {
Some(w) => {
let mp = w.get_mouse_pos(MouseMode::Discard);
debug!("mp = {:?}", mp);
match mp {
None => {
state.set_flag(Cond::Overflow, true);
}
Some((xf, yf)) => {
let xval = xf.round() as u64;
let yval = yf.round() as u64;
state.write(*x, xval);
state.write(*y, yval);
}
}
}
None => {
state.set_flag(Cond::Invalid, true);
}
}
}
ScreenOp::TestKey { pressed, code } => {
state.clear_status();
let num = num2key(state.read(*code)?);
let backend: &mut Backend = state.ext_mut();
match &mut backend.window {
Some(w) => {
match num {
None => {
state.set_flag(Cond::Invalid, true);
}
Some(kn) => {
let down = w.is_key_down(kn) as u64;
state.write(*pressed, down)?;
state.update_status(down);
}
}
}
None => {
state.set_flag(Cond::Invalid, true);
}
}
}
ScreenOp::TestMouse { pressed, button } => {
state.clear_status();
let omb = match state.read(*button)? {
0 => Some(MouseButton::Left),
1 => Some(MouseButton::Right),
2 => Some(MouseButton::Middle),
_ => {
state.set_flag(Cond::Invalid, true);
None
}
};
let backend: &mut Backend = state.ext_mut();
match &mut backend.window {
Some(w) => {
if let Some(mb) = omb {
let is_pressed = w.get_mouse_down(mb) as u64;
state.write(*pressed, is_pressed)?;
state.update_status(is_pressed);
}
}
None => {
state.set_flag(Cond::Invalid, true);
}
}
}
}
Ok(eres)
@ -132,7 +234,12 @@ impl OpTrait for ScreenOp {
ScreenOp::SetOpt { opt, val } => sexp::list(&[A("sc-opt"), A(opt), A(val)]),
ScreenOp::ScreenInit { width, height } => sexp::list(&[A("sc-init"), A(width), A(height)]),
ScreenOp::SetPixel { x, y, color } => sexp::list(&[A("sc-px"), A(x), A(y), A(color)]),
ScreenOp::Blit { force } => sexp::list(&[A("sc-blit"), A(force)])
ScreenOp::Blit { force } => sexp::list(&[A("sc-blit"), A(force)]),
ScreenOp::Update => sexp::list(&[A("sc-poll")]),
ScreenOp::GetMouse { x, y } => sexp::list(&[A("sc-mouse"), A(x), A(y)]),
ScreenOp::TestKey { pressed, code } => sexp::list(&[A("sc-key"), A(pressed), A(code)]),
ScreenOp::TestMouse { pressed, button } => sexp::list(&[A("sc-mbtn"), A(pressed), A(button)]),
ScreenOp::Erase { color } => sexp::list(&[A("sc-erase"), A(color)]),
}
}
}
@ -160,9 +267,6 @@ fn init(state: &mut RunState, width: Value, height: Value) -> Result<(), Fault>
backend.height = height as usize;
backend.buffer = vec![0; (width * height) as usize];
// window.limit_update_rate(Some(std::time::Duration::from_micros(16600)));
// window.limit_update_rate(None);
backend.window = Some(window);
blit_maybe(backend);
@ -177,9 +281,142 @@ fn blit_maybe(backend: &mut Backend) {
}
fn blit(backend: &mut Backend) {
backend.window.as_mut().unwrap()
.update_with_buffer(&backend.buffer, backend.width, backend.height)
let w = backend.window.as_mut().unwrap();
if !w.is_open() {
// TODO...
std::process::exit(0);
}
w.update_with_buffer(&backend.buffer, backend.width, backend.height)
.expect("Update screen"); // TODO fault
backend.last_render = Instant::now();
}
fn num2key(num : Value) -> Option<Key> {
let remap = [
Key::Key0,
Key::Key1,
Key::Key2,
Key::Key3,
Key::Key4,
Key::Key5,
Key::Key6,
Key::Key7,
Key::Key8,
Key::Key9,
Key::A, // 10
Key::B,
Key::C,
Key::D,
Key::E,
Key::F,
Key::G,
Key::H,
Key::I,
Key::J,
Key::K,
Key::L,
Key::M,
Key::N,
Key::O,
Key::P,
Key::Q,
Key::R,
Key::S,
Key::T,
Key::U,
Key::V,
Key::W,
Key::X,
Key::Y,
Key::Z, // 35
Key::F1, // 36
Key::F2,
Key::F3,
Key::F4,
Key::F5,
Key::F6,
Key::F7,
Key::F8,
Key::F9,
Key::F10,
Key::F11,
Key::F12,
Key::F13,
Key::F14,
Key::F15, // 50
Key::Down, // 51
Key::Left,
Key::Right,
Key::Up,
Key::Apostrophe,
Key::Backquote,
Key::Backslash, // 57
Key::Comma,
Key::Equal,
Key::LeftBracket,
Key::Minus,
Key::Period,
Key::RightBracket,
Key::Semicolon,
Key::Slash, // 65
Key::Backspace,
Key::Delete,
Key::End,
Key::Enter,
Key::Escape, // 70
Key::Home,
Key::Insert,
Key::Menu,
Key::PageDown,
Key::PageUp,
Key::Pause, // 76
Key::Space,
Key::Tab,
Key::NumLock,
Key::CapsLock,
Key::ScrollLock,
Key::LeftShift,
Key::RightShift,
Key::LeftCtrl,
Key::RightCtrl,
Key::NumPad0, // 86
Key::NumPad1,
Key::NumPad2,
Key::NumPad3,
Key::NumPad4,
Key::NumPad5,
Key::NumPad6,
Key::NumPad7,
Key::NumPad8,
Key::NumPad9,
Key::NumPadDot,
Key::NumPadSlash,
Key::NumPadAsterisk,
Key::NumPadMinus,
Key::NumPadPlus,
Key::NumPadEnter, // 100
Key::LeftAlt,
Key::RightAlt,
Key::LeftSuper,
Key::RightSuper,
];
if num < remap.len() as u64 {
Some(remap[num as usize])
} else {
None
}
}

@ -1,4 +1,4 @@
use crsn::asm::data::Rd;
use crsn::asm::data::{Rd, RdData};
use crsn::asm::error::CrsnError;
use crsn::asm::instr::op::OpKind;
use crsn::asm::parse::arg_parser::TokenParser;
@ -15,6 +15,16 @@ pub(crate) fn parse<'a>(keyword: &str, mut args: TokenParser<'a>) -> Result<Pars
}
}
"sc-erase" => {
ScreenOp::Erase {
color: if args.len() > 0 {
args.next_rd()?
} else {
Rd::immediate(0) // black
},
}
}
"sc-px" => {
ScreenOp::SetPixel {
x: args.next_rd()?,
@ -40,6 +50,31 @@ pub(crate) fn parse<'a>(keyword: &str, mut args: TokenParser<'a>) -> Result<Pars
}
}
"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()?
}
}
_other => {
return Ok(ParseRes::Unknown(args));
}

@ -0,0 +1,40 @@
(
(sc-init 640 480)
(sym x r6)
(sym y r7)
(def BOXSIZE 10)
(:loop)
(sc-poll)
(sc-mouse x y
(ov? (j :next)))
(sc-mbtn r0 0 (z? (j :next)))
(sym vx r0)
(sym vy r1)
(sym endx r2)
(sym endy r3)
(add endx x BOXSIZE)
(add endy y BOXSIZE)
(sub vy y BOXSIZE)
(:nextline)
(cmp vy endy (eq? (j :endbox)))
(sub vx x BOXSIZE)
(:nextpx)
(sc-px vx vy 0xffffff)
(inc vx)
(cmp vx endx
(eq? (inc vy)(j :nextline)))
(j :nextpx)
(:endbox)
(:next)
(sleep 20000)
(j :loop)
)
Loading…
Cancel
Save