Fontána by Řrřola [web]
; FON ,
; TA
; N
; A
; a 128-byte intro by rrrola <rrrola@gmail.com>
; greets to everyone who waits for the glitchy part
; DS (old) and ES (new) are arrays of max 16384 particles.
; Each particle is stored in 4 bytes: { s16 Y; s8 dY,dX; };
; If Y==0, the particle is uninitialized (also implies dX:dY==0).
; X is the address - there's only one particle per column.
;TODO: backbuffer could be ss, saves fs: prefix with [bp+di]
; do I even need a backbuffer?
; swap+clear could be copy+clear
org 100h ; assume ax=bx=0 cl=0xFF si=0x100 sp=di=-2 dx=cs<=0x50E4
les cx,[si+2] ; particles1: es=0x7B64 cx=0x8E02 ; C4 4C 02
mov fs,[byte si+E-100h] ; backbuffer: fs=0x60E4 ; 8E 64 7B
lds bp,[si] ; particles2: ds=0x8E02 bp=0x4CC4
rep stosw ; clear particles1
mov al,13h
int 10h ; 320x200, 256 colors
;main loop: add a new particle ; al=keypress
M:mov ax,0xBDF9 ; steady stream
xor di,di ; X=0 (center) Y=0xBDF9 (near the visible top)
stosw ; dY=0xF9 (slightly up) dX=0xBD (left)
;swap+clear particles1 and 2, copy+clear backbuffer ; di=2
push es
C:stosw ; clear particles2 (first pass: new particle's dX:dY)
push 0xA000
pop es ; screen: es = 0xA000
xchg ax,[fs:di]
stosw ; copy backbuffer to screen and clear it
dec di
dec di
push ds
pop es
mov ax,bx ;0
jnz C ;flags from "dec di"
pop ds
;for all particles1: ; si=X=index
P:mov di,si ; di=X
lodsw
or ax,ax ; ax=Y; if ==0, skip (uninitialized)
jz S ; (the dX:dY part is skipped next cycle)
; - add gravity
mov cx,0x0908 ; ch = color = blue, cl=8
inc word[si] ; dY++, can overflow to dX
; - for each neighbor: pull particle up ; bx=0
mov bl,256-2 ; bx = Xdiff; look only to the right
R:push ax
sub ax,[si+bx] ; ax = Ydiff = Y-Y2
cmp ax,[di] ; if Ydiff==Y, skip (uninitialized)
je F
or ah,ah ; if Ydiff>256, skip (too far)
jnz F
mov ch,0xF ; pull up: color = white
dec word[si] ; dY--, can overflow to dX
F:add bx,sp ;-4
pop ax
jns R
; - move particle, bounce if needed ; bx=-2
X:xchg ax,di ; 2 passes: first X, then Y
ror word[si],cl; swap bytes
xchg ax,bp
mov al,8
imul byte[si]
add ax,bp ; X += 8*dX, Y += 8*dY
jno B
mov al,[si] ; bounce, lose 1/4 speed
sar byte[si],2
sub [si],al
xchg ax,bp ; restore old position
B:inc bx
jnz X
; - find a free column, store new position and speed ; bx=0
H:scasw ; X+=4; X was already quantized to 4 bytes
scasw
cmp [es:di],bx
jnz H ; repeat until column is free
stosw ; store new Y
movsw ; store new dX:dY
; - plot particle
sar ax,cl ; ax = Yscreen (-128..127)
imul bp,ax,320 ; bp = Yadr
sar di,cl ; di = Xadr = Xscreen (-128..127)
mov [fs:bp+di+320*(100-28)+160],ch ; ch = blue or white
S:or si,si ; ah=0 if skipped (unitialized)
jnz P
;esc?
E:in al,60h ; E4 60
dec ax
jnz M
ret
[ back to the prod ]
