Add interactive mandelbrot example #24
Merged
MightyPork
merged 2 commits from cpsdqs/crsn:master
into master
4 years ago
@ -0,0 +1,243 @@ |
||||
( |
||||
(sc-init 1024 768) |
||||
(sc-opt SCREEN_AUTOBLIT 0) |
||||
(def W 1024) |
||||
(def H 768) |
||||
(def MAXITER 50) |
||||
|
||||
(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) |
||||
|
||||
; index into the skip/size table |
||||
(sym mb_skip_index r6) |
||||
|
||||
; size of big pixels |
||||
(def COL_SKIP 8) |
||||
(def ROW_SKIP 8) |
||||
; incrementally renders 1x1, 2x2, 4x4, ... |
||||
(def MB_SKIP_TABLE_SIZE 80) |
||||
(def MB_SKIP_REPEAT_INDEX 16) |
||||
(sym mb_skip_table_x r7) |
||||
(sym mb_skip_table_y r8) |
||||
(sym mb_size_table r12) |
||||
(mkbf mb_skip_table_x ( |
||||
0 4 0 4 2 6 0 2 4 6 2 6 0 2 4 6 |
||||
; 8x8 grid |
||||
1 3 5 7 1 3 5 7 1 3 5 7 1 3 5 7 |
||||
0 2 4 6 0 2 4 6 0 2 4 6 0 2 4 6 |
||||
1 3 5 7 1 3 5 7 1 3 5 7 1 3 5 7 |
||||
; do top left pixels again |
||||
0 2 4 6 0 2 4 6 0 2 4 6 0 2 4 6 |
||||
)) |
||||
(mkbf mb_skip_table_y ( |
||||
0 0 4 4 0 0 2 2 2 2 4 4 6 6 6 6 |
||||
; 8x8 grid |
||||
0 0 0 0 2 2 2 2 4 4 4 4 6 6 6 6 |
||||
1 1 1 1 3 3 3 3 5 5 5 5 7 7 7 7 |
||||
1 1 1 1 3 3 3 3 5 5 5 5 7 7 7 7 |
||||
; do top left pixels again |
||||
0 0 0 0 2 2 2 2 4 4 4 4 6 6 6 6 |
||||
)) |
||||
(mkbf mb_size_table ( |
||||
8 4 4 4 2 2 2 2 2 2 2 2 2 2 2 2 |
||||
; 8x8 grid |
||||
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 |
||||
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 |
||||
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 |
||||
; do top left pixels again |
||||
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 |
||||
)) |
||||
|
||||
(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 |
||||
; size - pixel size |
||||
; col - column offset |
||||
; px - offset x |
||||
; py - offset y |
||||
; scale - scaling |
||||
; row - row position |
||||
(proc render_row size 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)) |
||||
) |
||||
(sc-rect x y size size r0) |
||||
(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_skip_index 0) |
||||
(:did_not_move) |
||||
|
||||
(sym mb_col_skip r9) |
||||
(sym mb_row_skip r11) |
||||
(bfrd mb_col_skip @mb_skip_table_x mb_skip_index) |
||||
(bfrd mb_row_skip @mb_skip_table_y mb_skip_index) |
||||
(bfrd r1 @mb_size_table mb_skip_index) |
||||
|
||||
; render row mb_row + row skip |
||||
(ld r0 mb_row) |
||||
(add r0 mb_row_skip) |
||||
(call render_row r1 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_skip_index 1) |
||||
(ld is_first_render 0) |
||||
|
||||
(cmp mb_skip_index MB_SKIP_TABLE_SIZE) |
||||
; if skip index is out of bounds, go back to repeating area |
||||
(j.lt :not_end) |
||||
(ld mb_skip_index MB_SKIP_REPEAT_INDEX) |
||||
(:not_end) |
||||
(: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) |
||||
) |
||||
) |
||||
|
Loading…
Reference in new issue