Uzel by Řrřola [web]
; UZEL %define adr(x) byte si-100h+x org 100h ;assume ax=0 bx=0 cx=255 si=100h di=-2 bp=9??h sp=-2 dx=cs=ds=es=ss jmp B ;subroutine: draw a 32x32 sprite to xyz I imul bp,[bx],320 _320 equ $-2 add bp,[bx+di] ; bp = Y*320+X X xor ax,ax add al,[fs:bx] ;0..255 jz N add ax,dx shr ax,3 cmp [gs:bp+(100-16)*320+(160-16)],al jg N mov [gs:bp+(100-16)*320+(160-16)],al ;don't draw: we're outside of a sphere or behind something N inc bp add bl,8 jno X lea bp,[byte bp+si-100h+320-32] add bh,8 jno X fadd dword[adr(_2PIdiv256)] _2PIdiv256 ret db 0Fh, 0C9h, 3Ch ;= 0.0245436926 _1_5 _R dw 2, 3FC0h B push 0A000h mov al,13h _19 equ $-1 ;=19 add dh,al mov gs,dx ; gs = cs+1300h: 8-bit z-buffer int 10h pop es _7 equ $-1 ;=7 add dh,al mov fs,dx ; fs = cs+2600h: sprite depths pop ax ; sp=0, ax=0 ;palette: white->pink->black mov dx,3c8h R out dx,al mov dl,0c9h shld ax,cx,14 out dx,al mul cl mov al,ah out dx,al loop R ;precompute sphere sprites (for speed) ;has 8x8 sub-pixel accuracy, but it's unused in this intro Q mov ax,bx imul ax ; dx = ah*ah mov ax,bx imul al ; ax = al*al add ax,dx sub ax,128*128-64 push ax ; ax = -(128*128-64-x*x-y*y) fild word[di] fchs fsqrt fadd st0 fistp word[di] ; 0..255 pop ax mov [fs:bx],al ; sqrt(128*128-64-x*x-y*y); 0 if outside (8000h was stored for NaNs) inc bx jnz Q mov bx,8484h ;main loop M inc word[bx+si] fninit ;draw a trefoil to the z-buffer (512 sprites along the parametric equation) ;takes 4x"fsincos" per sphere, no big deal ;TODO:rotate ; w = cb*y + sb*z; z = -sb*y + cb*z; y = w; ; w = ca*x + sa*z; z = -sa*x + ca*z; x = w; mov ch,2 fldz ; {u=0} S fld st0 fsincos ; {su cu u} fld st2 fmul dword[adr(_1_5)]; {v=1.5*u su cu u} fsincos ; {sv cv su cu u} fiadd word[adr(_R)] ; {R+sv cv su cu u} fmul st2,st0 fmulp st3,st0 ; {z=cv y=(R+sv)su x=(R+sv)cu u} C fld st1 fld st1 fild word[bx+si] ; {t z y z y x u} fmul dword[adr(_2PIdiv256)] fsincos ; {st ct z y z y x u} fmul st2,st0 fmulp st3,st0 ; {ct st*z st*y z y x u} fmul st3,st0 fmulp st4,st0 ; {st*z st*y ct*z ct*y x u} faddp st3,st0 ; {st*y ct*z st*z+ct*y x u} fsubp st1,st0 ; {ct*z-st*y st*z+ct*y x u} fild word[bx+si] fidiv word[adr(_7)] fsin fimul word[adr(_7)] fiadd word[adr(_19)] ; w = 19 + 7*sin(t/7) fmulp st1,st0 fistp word[bx+di] ; {Y=w*(ct*z-st*y) st*z+ct*y x u} inc di inc di ; store Y to [bx+di] and X to [bx] jz C neg di ;project to screen: z has width 160 (and height too) ;TODO: z += BEAT_Z * (BEAT*t-(int)(BEAT*t)); ;TODO: want subpixel accuracy! ;always on the screen - no overflow tests necessary push si fimul word[di] ; {baseZ=z*256 u} fistp word[di] ; store baseZ {u} pop dx call I ; draw sprite to xy ;drawing done: loop over all sprites loop S ;wait for vertical retrace start (70 fps cap) mov dx,3DAh V in al,dx and al,8 jz V ;copy and clear screen pusha imul bx,[bx+si],321 xor si,si W mov al,-124 xchg al,[gs:si] add al,124 jnz Z ; empty: feedback mov al,[es:bx+si] shr al,1 Z not al stosb inc si inc bx loop W popa ;ESC test, maybe end in al,60h cmp al,1 ; clears carry jnz M int 20h
[ back to the prod ]