Gyroid by Řrřola [web]
; | | | | | | | | | | | ; +--+ +--+ +--+ +--+ +--+ +-- ; / \ / \ / \ / \ / \ / ;--+ Gyroid +--+ +--+ +--+ +--+ ; | a 128-byte intro by rrrola <[email protected]> ;--+ greets to everyone who's twisted their ankle ; \ / \ / \ / \ / \ / \ ; +--+ +--+ +--+ +--+ +--+ +-- ; | | | | | | | | | | | org 100h ; assume ah=bx=[-2]=0 si=0x100 di=sp=-2 [0xfd..ff]=0 ;68 f6 9f push 0xa000 - 160/16 lds bp,[si-3]; bp=0, ds=0x6800: sin table segment mov al,0x13 ;Palette: red and orange gradients P int 0x10 ; set 320x200 mode (on init) or palette color xor cx,cx shrd dx,bx,9 ; bl=index, dh=index/2, dl=(index+1)/4 jc Q ; if index%4<=1 then ch=dl: orange xchg dl,ch ; else ch=0: red Q mov ax,0x1010; set palette color: bl=index dh=R ch=G cl=B dec bx jnz P ; bx=0 ;Sin table with 16384 entries (for speed) fninit S mov bx,[bp+di] ; bx=[ss:bp+di]=[ss:-2]=angle (0 on init) fild word[bp+di] fidiv word[byte bp+si-0x100+K] fsin ;| sin(angle/65536*2pi): adjust period to 2*pi fstp dword[bx] add [bp+di],sp ; next angle (sp=-4) jnz S ; bx=4 pop es ; es=0x9ff6: centered screen segment ;For each pixel: initialize ray position X,Y,Z and direction dX,dY,dZ M mov ax,0xcccd mul di ; di=pixel address ;96 ; distance factor: float32(-0.21552)=0xbe5cb196 F xchg ax,si ; ax=X=0x3d28 (not on init) ;b1 5c mov cl,92 ; cl = 4 * 23(number of iterations) ;be 28 = 10430 ~ 65536/2pi K mov si,0x3d28; si=0x3d28 (exact sin->cos phase would be 0x4000) sub dh,cl ; dx=dY (centered), dl:bh=dX, cl:dh=dZ=0x5c?? pusha ; stack:[-9 -8 -7 -6 -5 -4 -3] ; bh dl dh cl ch al ah ; ( dY ) ; ( dX )( dZ ) cwd ; ax=X=0x3d28, dx=Y=0, bx=Z=time: orange helix ;Compute the distance to the gyroid G fld dword[bx+si] xchg ax,dx ;| cosZ | cosY | cosX xchg ax,bx ; cycle: ax=X dx=Y bx=Z -> ax=Z dx=X bx=Y fmul dword[bx] inc bp ;| cosZ*sinY | cosY*sinX | cosX*sinZ jpo G ; bp=3: loop thrice faddp faddp ;| d=cosZ*sinY+cosY*sinX+cosX*sinZ fist word[bp-7]; [-4](pushed ax) = round(d): +1 or -1 fabs ;| |d| fldl2e fsubp st1,st0;| |d|-1.442695 fmul dword[bp-3+F] ;| D=0.21552*(1.442695-|d|) ;Advance the ray position by the distance A fild word[bp-10] fmul st1 ;| dZ*D D | dY*D D | dX*D D fistp word[bp+si] xchg ax,dx xchg ax,bx ; cycle: ax=X dx=Y bx=Z -> ax=Z dx=X bx=Y add ax,[bp+si]; Z+=dZ*D | Y+=dY*D | X+=dX*D and al,0xfc ; align to a multiple of 4 (for the sin table) dec cx ; cx-=3 dec bp jnz A ; bp=0 ("loopnz" would save a byte but it's slow) ;Close enough? fstp dword[bp+si] cmp [bp+si+2],si jl T ; hit if D<0.041 (= signed_bits_float32(D)<0x3d280000) loop G ; max 23 iterations ;Add texture, draw pixel T and ah,0xc ; wood-like stripes perpendicular to x add cl,ah add [bp-4],cx; [-4](pushed ax) += number of iterations inc di ; set zero flag popa stosb ; al=color jnz M ;Next frame inc bh ; time++ (slower) ; add bh,bl ; time+=4 (faster) jmp M ; loop forever ; in al,0x60 ; esc check ; dec ax ; jnz M ; ret
[ back to the prod ]