forked from MightyPork/crsn
				
			
						commit
						191ba495f2
					
				| @ -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