From ae82157d19f31bf16026ea71f356e24828dab05d Mon Sep 17 00:00:00 2001 From: cpsdqs Date: Sat, 24 Oct 2020 23:27:16 +0200 Subject: [PATCH] Add interactive mandelbrot example --- .../mandelbrot/mandelbrot-interactive.csn | 212 ++++++++++++++++++ 1 file changed, 212 insertions(+) create mode 100644 examples/mandelbrot/mandelbrot-interactive.csn diff --git a/examples/mandelbrot/mandelbrot-interactive.csn b/examples/mandelbrot/mandelbrot-interactive.csn new file mode 100644 index 0000000..4c2ab2a --- /dev/null +++ b/examples/mandelbrot/mandelbrot-interactive.csn @@ -0,0 +1,212 @@ +( + (sc-init 1024 768) + (sc-opt SCREEN_AUTOBLIT 0) + (def W 1024) + (def H 768) + (def MAXITER 50) + + ; size of big pixels + (def COL_SKIP 8) + (def ROW_SKIP 8) + + (lds @cout "Interactive Mandelbrot\n") + (lds @cout "----------------------\n") + (lds @cout "Navigate using WASD, zoom using Q/E\n") + (lds @cout "To get a high-res image, stop interacting for while\n") + + (sym asciigr r10) + + (sym mb_x r2) + (sym mb_y r3) + (sym mb_s r4) + (sym mb_row r5) + (sym mb_col_skip r6) + (sym mb_row_skip r7) + + (ld mb_x 0.0) + (ld mb_y 0.0) + (ld mb_s 1.0) + (sym did_change r14) + (sym is_first_render r15) + (ld is_first_render 1) + + ; render row + ; big - is this the first render? if yes, use big pixels + ; col - mb_col_skip column offset + ; px - offset x + ; py - offset y + ; scale - scaling + ; row - row position + (proc render_row big col px py scale row + (sym gradient r9) + (mkbf gradient ( + 0x421e0f 0x19071a 0x09012f 0x040449 0x000764 0x0c2c8a 0x1852b1 0x397dd1 + 0x86b5e5 0xd3ecf8 0xf1e9bf 0xf8c95f 0xffaa00 0xcc8000 0x995700 0x6a3403)) + + (sym x r7) + (sym y r8) + (add y row) + (ld x col) + (:col) + (call pixel x y px py scale) + (sub r0 MAXITER 1) + (rcmp res0 1 r0 + (eq? + (mod r0 res0 16) + (bfrd r0 @gradient r0) + ) + (else? (ld r0 0)) + ) + (cmp big 1) + (j.ne :not_big) + (sc-rect x y COL_SKIP ROW_SKIP r0) + (j :was_big) + (:not_big) + (sc-wr x y r0) + (:was_big) + (add x COL_SKIP) + (cmp x W) + (j.lt :col) + (sc-blit) + (ret)) + + (:slp) + (sc-poll) + ; did_change -- did the user interact during this frame? + (ld did_change 0) + + ; scaled movement speed in r1 + (fdiv r1 0.03 mb_s) + + ; A < + (sc-key r0 KEY_A) + (j.z :a_not_pressed) + (fsub mb_x r1) + (ld did_change 1) + (:a_not_pressed) + + ; W ^ + (sc-key r0 KEY_W) + (j.z :w_not_pressed) + (fsub mb_y r1) + (ld did_change 1) + (:w_not_pressed) + + ; S v + (sc-key r0 KEY_S) + (j.z :s_not_pressed) + (fadd mb_y r1) + (ld did_change 1) + (:s_not_pressed) + + ; D > + (sc-key r0 KEY_D) + (j.z :d_not_pressed) + (fadd mb_x r1) + (ld did_change 1) + (:d_not_pressed) + + ; Q + + (sc-key r0 KEY_Q) + (j.z :q_not_pressed) + (fmul mb_s 1.01) + (ld did_change 1) + (:q_not_pressed) + + ; E - + (sc-key r0 KEY_E) + (j.z :e_not_pressed) + (fdiv mb_s 1.01) + (ld did_change 1) + (:e_not_pressed) + + (cmp did_change 0) + (j.eq :did_not_move) + ; if something changed... + + ; mark this as a first render and reset col_skip and row_skip + (ld is_first_render 1) + (ld mb_col_skip 0) + (ld mb_row_skip 0) + (:did_not_move) + + ; render row mb_row + mb_row_skip + (ld r0 mb_row) + (add r0 mb_row_skip) + (call render_row is_first_render mb_col_skip mb_x mb_y mb_s r0) + + (cmp mb_row H) + (j.ge :render_done) + ; if mb_row < H + (add mb_row ROW_SKIP) + (j :render_not_done) + (:render_done) + ; otherwise, this frame is done + (ld mb_row 0) + (add mb_col_skip 1) + (ld is_first_render 0) + (mod mb_col_skip COL_SKIP) + + ; if mb_col_skip wrapped back to zero increase mb_row_skip + (cmp mb_col_skip 0) + (j.ne :not_col) + (add mb_row_skip 1) + (mod mb_row_skip ROW_SKIP) + (:not_col) + (:render_not_done) + (j :slp) + + (proc pixel xi yi off_x off_y scale + (sym x0 r7) + (sym y0 r8) + (itf x0 xi) + (itf y0 yi) + + ; Scale to the interesting range x -2.5..1 and y -1..1 + (itf r0 W) + (itf r1 H) + + (fdiv x0 r0) + (fmul x0 3.5) + (fsub x0 2.5) + + (fdiv y0 r1) + (fmul y0 2.4) + (fsub y0 1.2) + + (fdiv x0 scale) + (fdiv y0 scale) + (fadd x0 off_x) + (fadd y0 off_y) + + (sym x r5) + (sym y r6) + (ld x 0.0) + (ld y 0.0) + (sym iter r4) + + (:iter) + (cmp iter MAXITER) + (j.eq :end) + (fmul r0 x x) + (fmul r1 y y) + (fadd r2 r1) + (fcmp r2 4.0) + (j.gt :end) + + (fsub r2 r0 r1) + (fadd r2 x0) + + (fmul r0 x y) + (fmul r0 2.0) + (fadd r0 y0) + (ld y r0) + (ld x r2) + (inc iter) + (j :iter) + + (:end) + (ret iter) + ) +) +