forked from MightyPork/crsn
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
243 lines
5.6 KiB
243 lines
5.6 KiB
(
|
|
(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)
|
|
)
|
|
)
|
|
|
|
|