Puls by Řrřola [web]
; P L a 256-byte intro by Rrrola - final version ; \ / \ rrrola@gmail.com ; U S http://rrrola.wz.cz ; greets to everyone who came to Riverwash 2009 ;%define BLOWUP 86 ; "ambient occlusion" strength (default 86: -1 byte) MAXSTEPSHIFT equ 6 ; shading strength (>=6 unless BLOWUP defined) MAXITERS equ 26 BASECOLOR equ -34 %define BLOCKS ; render 4x1 blocks (for slower machines, +3 bytes) org 100h ; assume ah=bx=0 cx=255 sp=di=-2 si=100h mov al,13h ;<(byte)[100h]>>8 = 0.6875 push bx ; (word)[100h]>>16 = 0.0769 mov dx,3C8h ; (float)[100h] = -0.0008052 int 10h ;palette - 4 gradients of 32 shades P mov al,bl ;<set al on 1st pass, then each red and green Q test bl,cl ; parity: eooooeoeoeee eooooeoeoeee ... jpe E ; index: #0gb1gb2gb3g b4gb5gb6gb7g ... imul al shr ax,7 E imul bl mov al,ah out dx,al mov dl,0c9h loop P mov cl,3 dec bx jnz Q push 09FCEh ;<aligns with the screen ;-) pop es mov bh,56h ; xyz addressing trick from neon_station ; vecNN = (words){[5600h+N] [5656h+N] [56ACh+N]} ;frame loop - prepare constants ;ax=key bx=5600h bp=dx=0 cx=3 si=100h di=-2 sp=-4 word[5700h]=T M fninit ; {} = fpu stack add word[bx+si],byte 88 ; T++ fild word[bx+si] ;=14.00564 * 2pi fsincos ; {s=sin(T*0.00564) c=cos(T*0.00564)} fdiv st1,st0 ; {s t=cotg(T*0.00564)} fild word[bx+si] fmul dword[si] fsin fimul word[si] ; {r>>16=0.0769*sin(T*-0.0708) s t} pop edx ;=9B6C0000... just get rid of it push es push bp ;dword[-4]=9FCE0000h ;pixel loop ;x = word[-3] ~ -0.5..0.5 (+= 0.003125 each column) ;y = word[-2] ~ -0.4..0.4 (+= 0.00390625 each row) X %ifdef BLOCKS test bp,cx ; 4x1 blocks: keep last color? jnz D %endif pusha ;[-20 -18 -16 -14 -12 -10 -8 -6 -4 -2 ] ; di si bp sp bx dx cx ax yyyy ; FEFF0001adr FCFF005600000300col ..xxxx ;fisheye projection: z = C-x*x-y*y mov [bx],bx ;=0.33594 Z mov ax,[di] fild word[di] imul ax sub [bx],dx dec di jpo Z ;di=-4 fild word[bx] ; {z>>16=0.33594-x*x-y*y x y r s t} ;advance x and y for next pixel (low word) %ifdef BLOCKS add word[di],3334h %else add dword[di],0000CCCDh %endif ;rotate direction vector R fmul st4 ; {sz x y r s t} fld st0 fmul st6 ; {cz sz x y r s t} fxch st2 fmul st5 fsub st2,st0; {sx sz cz-sx y r s t} fmul st6 faddp st1,st0; {cx+sz cz-sx y r s t} fxch st2 ; {y cz-sx cx+sz r s t} inc di jpo R dec di ;di=-2 ; {X Y Z r s t} ;advance x and y for next pixel (high word) %ifdef BLOCKS adc word[di],cx %endif ;store ray origin and direction vector imul dx,[bx+si],byte 10;=0.0134*T S fistp word[bx+di] ; d>>16 = v-2 = {X, Y, Z} ;fistp dword[bx+di] ;<slower, but fixes corners (+3 bytes) ;sar dword[bx+di],1 mov [bx],dx add dh,[si] ; o>>16 = v0 = 0.0134*T + {0, 0.6875, 0.375} add bl,bh jnc S ;bl=2 ; {r s t} ;intersect ray with scene, count number of bounding volume misses cwd ; dx = hit(-1|0): grainy rendering mov ah,-MAXITERS ; ah = iters(-MAXITERS..0), al = hue(0..3) ;cwd ;<for smooth rendering with bands %ifdef BLOWUP mov cx,BLOWUP*256+MAXSTEPSHIFT; cl = stepshift(0..MAXSTEPSHIFT) %else adc cx,bx ;=86*256 + 6 ;-) %endif call I sub ah,cl aad 4 ;ah=0 add al,MAXITERS*4+BASECOLOR mov [di-4],ax ; pushed ax = color = (iters-stepshift)*4 + hue popa ;draw pixel D %ifdef BLOCKS mov [es:bp+si],al inc bp %else inc bp mov [es:bp+si],al %endif jnz X ; 65536 pixels ;next frame: fall through on esc - ah=word[sp]=0 in al,60h dec ax jnz M ;<assume no one presses ESC after 1 frame ;) ;raycasting using unbounded binary search ;start with the smallest step size ;v-2 = d = {dx, dy, dz} ;v0 = o = current {x, y, z} mod 1 ;last probe was inside: halve step and go back ; outside: double step and go forward I mov bl,0 ;bl=0 A mov bp,[bx+di] ; hit ? (o -= d>>stepshift) : (o += d>>stepshift) sar bp,cl xor bp,dx add [bx],bp add bl,bh jnc A ;bl=2 salc ;al=FFh fist word[bx+si] ; word[5702h] = r ;bounding volumes: "blow up" the scene by the current step size push cx shr cx,cl add ch,37 ; cx = hitlimit = 0.1445 + (BLOWUP >> stepshift+8) ;inside test ;hue=[0,1] ;green octahedra: (|x|+|y|+|z|)/2 - 0.1445 + r < blowup ;orange octahedra: (|x+0.5|+|y+0.5|+|z+0.5|)/2 - 0.1445 - r < blowup O mov dx,[bx+si] ; dx = [r,-r] neg word[bx+si] C imul bp,ax,32768 ; bp = [0.5, 0] - v0.xyz sub bp,[bx+di] jns T neg bp T shr bp,1 add dx,bp ; v2 = |signed(bp)|/2 mov [bx],bp add bl,bh jnc C ;bl=4 ; dx = sum(v2) + [r,-r] cmp dx,cx ; if (dx < hitlimit) hit! inc ax ;al=0,ah++ jc H mov bl,2 ;bl=2 jpe O ;al=1 ; repeat if al==0 ;hue=[2,3] ;bars: (||x|-|z|| + ||y|-|x|| + ||z|-|y||)/2 - 0.0676 < blowup ;bolts: (||x|-|z|| + ||y|-|x|| + ||z|-|y||)/2 - 0.1445 < blowup sub dx,[bx+si] inc ax ;al=2 ;sub dx,bx ;<simple bolt movement: sum(v2)-2*r-0.3359 sub dx,[bx+si] ;<precise bolt movement: sum(v2)-3*r-0.375 sub dh,60h ; (+3 bytes) imul dx,byte 13 ; if (|sum(v2)-3*r-0.375| < 0.03846) mov dx,[si] ; dx = extra_width = 0.0769, hue = 2 jo B ; else inc ax ;al=3 ; dx = extra_width = 0, hue = 3 cwd B sub bp,[bx] ; bp = v2.zxy - v2.xyz jns L neg bp L add dx,bp mov bp,[bx] add bl,bh jnc B ;bl=4 ; dx = sum(|signed(bp)|) + extra_width cmp dx,cx ; if (dx < hitlimit) hit! ;adjust step size according to the hit result H pop cx ;cf=hit sbb dx,dx ; dx = hit?-1:0 cmc sbb cl,dl ; if (hit) stepshift++ adc cl,dl ; else if (stepshift > 0) stepshift-- ;more probes? cmp cl,MAXSTEPSHIFT jae F ; if (stepshift >= maxstepshift) break add ah,dl ; iters++, if (hit) iters-- jne I ; if (iters >= maxiters) break F ret
[ back to the prod ]