diff --git a/README.md b/README.md index e5572db..d53e878 100644 --- a/README.md +++ b/README.md @@ -783,6 +783,7 @@ such as animations. ; Check key status. Keys are 0-127. Reads 1 if the key is pressed, 0 if not. ; A list of supported keys can be found in the extension source code. +; Run the example screen_keys.scn to interactively check key codes. (sc-key Wr'pressed Rd'num) ; Check mouse button state. @@ -790,6 +791,18 @@ such as animations. (sc-mbtn Wr'pressed Rd'btn) ``` +Available constants provided by the module: + +- SCREEN_AUTO_BLIT, SCREEN_FPS, SCREEN_UPSCALE, +- MBTN_LEFT, MBTN_RIGHT, MBTN_MIDDLE (MBTN_MID) +- KEY_0, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7, KEY_8, KEY_9 (0-9) +- KEY_A, 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 (10-35) +- KEY_F1, 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, +- KEY_Down, KEY_Left, KEY_Right, KEY_Up, KEY_Apos, KEY_Backtick, KEY_Backslash, KEY_Comma, KEY_Equal, KEY_BracketL, KEY_Minus, KEY_Period, KEY_BracketR, KEY_Semicolon, KEY_Slash, KEY_Backspace, KEY_Delete, KEY_End, KEY_Enter, KEY_Escape, KEY_Home, KEY_Insert, KEY_Menu, KEY_PageDown, KEY_PageUp, KEY_Pause, KEY_Space, KEY_Tab, KEY_NumLock, KEY_CapsLock, KEY_ScrollLock, +- KEY_KP0, KEY_KP1, KEY_KP2, KEY_KP3, KEY_KP4, KEY_KP5, KEY_KP6, KEY_KP7, KEY_KP8, KEY_KP9, +- KEY_KPDot, KEY_KPSlash, KEY_KPAsterisk, KEY_KPMinus, KEY_KPPlus, KEY_KPEnter, +- KEY_ShiftL, KEY_ShiftR, KEY_CtrlL, KEY_CtrlR, KEY_AltL, KEY_AltR, KEY_WinL, KEY_WinR, + ### Graphic acceleration commands ``` diff --git a/crsn_screen/src/exec.rs b/crsn_screen/src/exec.rs index b8cb7cb..c532b32 100644 --- a/crsn_screen/src/exec.rs +++ b/crsn_screen/src/exec.rs @@ -4,7 +4,6 @@ use std::time::{Duration, Instant}; use minifb::{Key, MouseButton, MouseMode, ScaleMode, Window, WindowOptions}; use crsn::asm::data::literal::{Value, is_negative}; -use crsn::asm::error::CrsnError; use crsn::asm::instr::cond::Flag; use crsn::module::{EvalRes, OpTrait}; use crsn::runtime::fault::Fault; @@ -55,7 +54,7 @@ impl Default for Backend { } impl Backend { - pub fn draw_rect_log(&mut self, mut x: Value, mut y: Value, w: Value, h: Value, color: u32) { + pub fn draw_rect_log(&mut self, x: Value, y: Value, w: Value, h: Value, color: u32) { for yy in (y * self.opts.upscale)..((y + h) * self.opts.upscale).min(self.height) { for xx in (x * self.opts.upscale)..((x + w) * self.opts.upscale).min(self.width) { self.buffer[(yy * self.width + xx) as usize] = color as u32; @@ -414,7 +413,7 @@ fn blit(backend: &mut Backend) -> Result<(), Fault> { fn num2key(num: Value) -> Option { let remap = [ - Key::Key0, + Key::Key0, // 0 Key::Key1, Key::Key2, Key::Key3, @@ -423,28 +422,29 @@ fn num2key(num: Value) -> Option { Key::Key6, Key::Key7, Key::Key8, - Key::Key9, + Key::Key9, // 9 + Key::A, // 10 Key::B, Key::C, Key::D, Key::E, - Key::F, + Key::F, // 15 Key::G, Key::H, Key::I, Key::J, - Key::K, + Key::K, // 20 Key::L, Key::M, Key::N, Key::O, - Key::P, + Key::P, // 25 Key::Q, Key::R, Key::S, Key::T, - Key::U, + Key::U, // 30 Key::V, Key::W, Key::X, @@ -455,12 +455,12 @@ fn num2key(num: Value) -> Option { Key::F2, Key::F3, Key::F4, - Key::F5, + Key::F5, // 40 Key::F6, Key::F7, Key::F8, Key::F9, - Key::F10, + Key::F10, // 45 Key::F11, Key::F12, Key::F13, @@ -468,18 +468,18 @@ fn num2key(num: Value) -> Option { Key::F15, // 50 Key::Down, // 51 - Key::Left, - Key::Right, - Key::Up, + Key::Left, // 52 + Key::Right, // 53 + Key::Up, // 54 Key::Apostrophe, - Key::Backquote, + Key::Backquote, // 56 (a backtick) Key::Backslash, // 57 Key::Comma, Key::Equal, - Key::LeftBracket, + Key::LeftBracket, // 60 [ Key::Minus, Key::Period, - Key::RightBracket, + Key::RightBracket, // 63 ] *This does not work due to a bug in the library we use - PR is sent upstream https://github.com/emoon/rust_minifb/pull/222* Key::Semicolon, Key::Slash, // 65 Key::Backspace, diff --git a/crsn_screen/src/lib.rs b/crsn_screen/src/lib.rs index c95e975..65739c2 100644 --- a/crsn_screen/src/lib.rs +++ b/crsn_screen/src/lib.rs @@ -8,6 +8,7 @@ use crsn::module::{CrsnExtension, ParseRes}; use crsn::sexp::SourcePosition; use crsn::asm::data::literal::Value; use crate::exec::{OPT_AUTO_BLIT, OPT_FRAME_RATE, OPT_UPSCALE}; +use minifb::Key; mod defs; mod parse; @@ -36,9 +37,124 @@ impl CrsnExtension for ScreenOps { fn get_constant_value<'a>(&self, name: &str) -> Option { match name { - "SCREEN_AUTO_BLIT" => Some(OPT_AUTO_BLIT), + "SCREEN_AUTO_BLIT" | "SCREEN_AUTOBLIT" => Some(OPT_AUTO_BLIT), "SCREEN_FPS" => Some(OPT_FRAME_RATE), "SCREEN_UPSCALE" => Some(OPT_UPSCALE), + + "MBTN_LEFT" => Some(0), + "MBTN_RIGHT" => Some(1), + "MBTN_MIDDLE" | "MBTN_MID" => Some(2), + + "KEY_0" => Some(Key::Key0 as Value), // 0 + "KEY_1" => Some(Key::Key1 as Value), + "KEY_2" => Some(Key::Key2 as Value), + "KEY_3" => Some(Key::Key3 as Value), + "KEY_4" => Some(Key::Key4 as Value), + "KEY_5" => Some(Key::Key5 as Value), + "KEY_6" => Some(Key::Key6 as Value), + "KEY_7" => Some(Key::Key7 as Value), + "KEY_8" => Some(Key::Key8 as Value), + "KEY_9" => Some(Key::Key9 as Value), // 9 + + "KEY_A" => Some(Key::A as Value), // 10 + "KEY_B" => Some(Key::B as Value), + "KEY_C" => Some(Key::C as Value), + "KEY_D" => Some(Key::D as Value), + "KEY_E" => Some(Key::E as Value), + "KEY_F" => Some(Key::F as Value), // 15 + "KEY_G" => Some(Key::G as Value), + "KEY_H" => Some(Key::H as Value), + "KEY_I" => Some(Key::I as Value), + "KEY_J" => Some(Key::J as Value), + "KEY_K" => Some(Key::K as Value), // 20 + "KEY_L" => Some(Key::L as Value), + "KEY_M" => Some(Key::M as Value), + "KEY_N" => Some(Key::N as Value), + "KEY_O" => Some(Key::O as Value), + "KEY_P" => Some(Key::P as Value), // 25 + "KEY_Q" => Some(Key::Q as Value), + "KEY_R" => Some(Key::R as Value), + "KEY_S" => Some(Key::S as Value), + "KEY_T" => Some(Key::T as Value), + "KEY_U" => Some(Key::U as Value), // 30 + "KEY_V" => Some(Key::V as Value), + "KEY_W" => Some(Key::W as Value), + "KEY_X" => Some(Key::X as Value), + "KEY_Y" => Some(Key::Y as Value), + "KEY_Z" => Some(Key::Z as Value), // 35 + + "KEY_F1" => Some(Key::F1 as Value), // 36 + "KEY_F2" => Some(Key::F2 as Value), + "KEY_F3" => Some(Key::F3 as Value), + "KEY_F4" => Some(Key::F4 as Value), + "KEY_F5" => Some(Key::F5 as Value), // 40 + "KEY_F6" => Some(Key::F6 as Value), + "KEY_F7" => Some(Key::F7 as Value), + "KEY_F8" => Some(Key::F8 as Value), + "KEY_F9" => Some(Key::F9 as Value), + "KEY_F10" => Some(Key::F10 as Value), // 45 + "KEY_F11" => Some(Key::F11 as Value), + "KEY_F12" => Some(Key::F12 as Value), + "KEY_F13" => Some(Key::F13 as Value), + "KEY_F14" => Some(Key::F14 as Value), + "KEY_F15" => Some(Key::F15 as Value), // 50 + + "KEY_Down" => Some(Key::Down as Value), // 51 + "KEY_Left" => Some(Key::Left as Value), // 52 + "KEY_Right" => Some(Key::Right as Value), // 53 + "KEY_Up" => Some(Key::Up as Value), // 54 + "KEY_Apos" => Some(Key::Apostrophe as Value), + "KEY_Backtick" => Some(Key::Backquote as Value), // 56 (a backtick) + "KEY_Backslash" => Some(Key::Backslash as Value), // 57 + "KEY_Comma" => Some(Key::Comma as Value), + "KEY_Equal" => Some(Key::Equal as Value), + "KEY_BracketL" => Some(Key::LeftBracket as Value), // 60 [ + "KEY_Minus" => Some(Key::Minus as Value), + "KEY_Period" => Some(Key::Period as Value), + "KEY_BracketR" => Some(Key::RightBracket as Value), // 63 ] *This does not work due to a bug in the library we use - PR is sent upstream https://github.com/emoon/rust_minifb/pull/222* + "KEY_Semicolon" => Some(Key::Semicolon as Value), + "KEY_Slash" => Some(Key::Slash as Value), // 65 + "KEY_Backspace" => Some(Key::Backspace as Value), + "KEY_Delete" => Some(Key::Delete as Value), + "KEY_End" => Some(Key::End as Value), + "KEY_Enter" => Some(Key::Enter as Value), + "KEY_Escape" => Some(Key::Escape as Value), // 70 + "KEY_Home" => Some(Key::Home as Value), + "KEY_Insert" => Some(Key::Insert as Value), + "KEY_Menu" => Some(Key::Menu as Value), + "KEY_PageDown" => Some(Key::PageDown as Value), + "KEY_PageUp" => Some(Key::PageUp as Value), + "KEY_Pause" => Some(Key::Pause as Value), // 76 + "KEY_Space" => Some(Key::Space as Value), + "KEY_Tab" => Some(Key::Tab as Value), + "KEY_NumLock" => Some(Key::NumLock as Value), + "KEY_CapsLock" => Some(Key::CapsLock as Value), + "KEY_ScrollLock" => Some(Key::ScrollLock as Value), + "KEY_ShiftL" => Some(Key::LeftShift as Value), + "KEY_ShiftR" => Some(Key::RightShift as Value), + "KEY_CtrlL" => Some(Key::LeftCtrl as Value), + "KEY_CtrlR" => Some(Key::RightCtrl as Value), + "KEY_KP0" => Some(Key::NumPad0 as Value), // 86 + "KEY_KP1" => Some(Key::NumPad1 as Value), + "KEY_KP2" => Some(Key::NumPad2 as Value), + "KEY_KP3" => Some(Key::NumPad3 as Value), + "KEY_KP4" => Some(Key::NumPad4 as Value), + "KEY_KP5" => Some(Key::NumPad5 as Value), + "KEY_KP6" => Some(Key::NumPad6 as Value), + "KEY_KP7" => Some(Key::NumPad7 as Value), + "KEY_KP8" => Some(Key::NumPad8 as Value), + "KEY_KP9" => Some(Key::NumPad9 as Value), + "KEY_KPDot" => Some(Key::NumPadDot as Value), + "KEY_KPSlash" => Some(Key::NumPadSlash as Value), + "KEY_KPAsterisk" => Some(Key::NumPadAsterisk as Value), + "KEY_KPMinus" => Some(Key::NumPadMinus as Value), + "KEY_KPPlus" => Some(Key::NumPadPlus as Value), + "KEY_KPEnter" => Some(Key::NumPadEnter as Value), // 100 + + "KEY_AltL" => Some(Key::LeftAlt as Value), + "KEY_AltR" => Some(Key::RightAlt as Value), + "KEY_WinL" | "KEY_SuperL" | "KEY_MetaL" => Some(Key::LeftSuper as Value), + "KEY_WinR" | "KEY_SuperR" | "KEY_MetaR" => Some(Key::RightSuper as Value), _ => None } } diff --git a/examples/life.csn b/examples/life.csn index 26a3375..1f40bce 100644 --- a/examples/life.csn +++ b/examples/life.csn @@ -1,130 +1,125 @@ ( ; simple GOL with screen and a buffer + DRAWING!!! - - ; Middle-click to payse or resume + + ; Middle-click to payse or resume ; (hold the button until paused - there is a sleep between generations and checking buttons) ; ; When paused, draw with left (white) and right (black) mouse buttons ; ; Resume by clicking middle again. - + (def GENERATION_MS 200) ; Real pixel size (sc-init 400 400) ; Upscaling factor (bug pixels) (sc-opt SCREEN_UPSCALE 10) - + ; Number of big pixels (def W 40) (def H 40) - + ; !!! If you change size, also update the following constants. ; Compile-time math is not implemented yet. - + (def XMAX 39) ; W-1 (def YMAX 39) ; H-1 (def NCELLS 1600) ; W*H - + ; --- end of config --- (sc-opt SCREEN_AUTO_BLIT 0) - + (sc-erase 0) ; all black (sym ng g15) (mkbf ng NCELLS) - + ; one glider (bfwr @ng 1 1) (bfwr @ng 42 1) (bfwr @ng 80 1) (bfwr @ng 81 1) (bfwr @ng 82 1) - + ; another glider (bfwr @ng 16 1) (bfwr @ng 55 1) (bfwr @ng 95 1) (bfwr @ng 96 1) (bfwr @ng 97 1) - - - (def LBTN 0) - (def RBTN 1) - (def MBTN 2) - + (:loop) (sc-poll) - + ; Drawing - (sc-mbtn _ MBTN + (sc-mbtn _ MBTN_MID (nz? (:release) (sc-poll) (mslp 10) - (sc-mbtn _ MBTN (nz? (j :release))) - + (sc-mbtn _ MBTN_MID (nz? (j :release))) + (:mousing) (sc-poll) (mslp 10) - + (ld r3 -1) - - (sc-mbtn _ LBTN) + + (sc-mbtn _ MBTN_LEFT) (ld.nz r3 1) - (sc-mbtn _ RBTN) + (sc-mbtn _ MBTN_RIGHT) (ld.nz r3 0) - + (tst r3 (nneg? (sc-mouse r0 r1) - + (tst r3) (sc-wr.nz r0 r1 #ffffff) (sc-wr.z r0 r1 #000000) - + (sc-blit) (mul r1 W) (add r0 r1) (ld8 r3:8 r3) (bfwr @ng r0 r3) - )) - - (sc-mbtn _ MBTN + )) + + (sc-mbtn _ MBTN_MID (z? (j :mousing))) - + (:release2) (sc-poll) (mslp 10) - (sc-mbtn _ MBTN (nz? (j :release2))) + (sc-mbtn _ MBTN_MID (nz? (j :release2))) ) - ) - + ) + (call Display) (sc-blit) (mslp GENERATION_MS) (j :loop) - + (proc CountNeighbors x y (sym xx r4) (sym yy r5) (sym i r6) - (sym count r7) - + (sym count r7) + ; yeah this sucks. it's correct, though - + (:a) - (add yy y -1 (neg? (j :d))) + (add yy y -1 (neg? (j :d))) (add xx x -1 (neg? (j :b))) (mul i yy W) (add i xx) (bfrd r0 @ng i) (and r0 0xFF (nz? (inc count))) - + (:b) (mul i yy W) (add i x) (bfrd r0 @ng i) (and r0 0xFF (nz? (inc count))) - + (:c) (add xx x 1) (cmp xx W (ge? (j :d))) @@ -132,16 +127,16 @@ (add i xx) (bfrd r0 @ng i) (and r0 0xFF (nz? (inc count))) - - (:d) + + (:d) (add xx x -1 (neg? (j :f))) (mul i y W) (add i xx) (bfrd r0 @ng i) (and r0 0xFF (nz? (inc count))) - + ; there is no E - + (:f) (add xx x 1) (cmp xx W (ge? (j :g))) @@ -149,26 +144,26 @@ (add i xx) (bfrd r0 @ng i) (and r0 0xFF (nz? (inc count))) - + (:g) - (add yy y 1) + (add yy y 1) (cmp yy H (ge? (j :end))) (add xx x -1 (neg? (j :h))) (mul i yy W) (add i xx) (bfrd r0 @ng i) (and r0 0xFF (nz? (inc count))) - + (:h) - (add yy y 1) + (add yy y 1) (cmp yy H (ge? (j :end))) (mul i yy W) (add i x) (bfrd r0 @ng i) (and r0 0xFF (nz? (inc count))) - + (:i) - (add yy y 1) + (add yy y 1) (cmp yy H (ge? (j :end))) (add xx x 1) (cmp xx W (ge? (j :end))) @@ -176,59 +171,59 @@ (add i xx) (bfrd r0 @ng i) (and r0 0xFF (nz? (inc count))) - + (:end) (ret count) ) - + (proc Display ; display and calc next gen (sym x r4) (sym y r5) - (sym i r6) + (sym i r6) (:next) ; The lower byte contains 0 or 1 ; the second byte will be filled with the next gen - + (bfrd r0 @ng i) - + ; Show this gen - (and r0 0xFF + (and r0 0xFF (nz? (sc-wr x y 0xffffff)) (z? (sc-wr x y 0x000000))) - + (call CountNeighbors x y) - + ; stay: 2,3 ; die: >3 ; born: 3 - - (cmp res0 2 + + (cmp res0 2 (eq? (ld8 r0:8 r0)) ; stasis (ne? - (tst r0 - (z? - (cmp res0 3 (eq? (ld8 r0:8 1))) ; birth - ) - (nz? - (cmp res0 3 (eq? (ld8 r0:8 1))) ; stay alive + (tst r0 + (z? + (cmp res0 3 (eq? (ld8 r0:8 1))) ; birth + ) + (nz? + (cmp res0 3 (eq? (ld8 r0:8 1))) ; stay alive ) ) ) ) - + (bfwr @ng i r0) - + (inc i) (inc x) (cmp x W (ne? (j :next))) (ld x 0) (inc y) - (cmp y H + (cmp y H (eq? (j :next2))) (j :next) - + ; Shift all by 8 to the right (generation shift) (:next2) (dec i) diff --git a/examples/screen_keys.csn b/examples/screen_keys.csn new file mode 100644 index 0000000..15b7849 --- /dev/null +++ b/examples/screen_keys.csn @@ -0,0 +1,58 @@ +( + ; Helper to check key codes of physical keys + + (sc-init 200 200) + (lds @cout "Press keys in the window to see their codes...\n") + (sym pressed r15) + (mkbf pressed 256) + (:loop) + (sc-poll) + (mslp 10) + (sym cnt r14) + (ld cnt 0) + (:next) + (sc-key _ cnt + (inval? (nop)) + (nz? + (bfrd r1 @pressed cnt + (z? + (call printnum cnt) + (lds @cout " PRESS\n") + (bfwr @pressed cnt 1) + (rng r0 0 #ffffff) + (sc-erase r0) + (sc-blit) + ) + ) + ) + (z? + (bfrd r1 @pressed cnt + (nz? + (call printnum cnt) + (lds @cout " RELEASE\n") + (bfwr @pressed cnt 0) + ) + ) + ) + ) + (inc cnt) + (cmp cnt 256 (ne? (j :next))) + (j :loop) + + ; this is a version if itoa that prints a number + (proc printnum num + (mkbf r15) + (ld r1 num) + (tst r1 (<0? (mul r1 -1))) + (:next) + (mod r0 r1 10) + (add r0 '0') + (bfrpush @r15 r0) + (div r1 10 (z? + (tst num (<0? (bfrpush @r15 '-'))) + (lds @cout @r15) + (del @r15) + (ret))) + (j :next) + ) +)