Nebe a duny by Řrřola [web]
; ___
; _ / __'__ Nebe a duny
; / \/__|_)\__ (Heaven and dunes)
; / /__ |__)\__ a 252-byte intro by rrrola
; ___ / +__ <rrrola@gmail.com>
; \ \/ | \\_/ greets to everyone
; \_/\__| /_/ who likes finding new ways
; .___/ to use old things
org 100h
SCREEN_OFFSET equ 0x800
;Init video mode: 640x480, 16 colors
mov al,12h
int 10h
push 0xa000
pop es
fninit
fldz ; t=time
;Wait for vertical retrace start
M:mov dx,0x3da
W:in al,dx
and al,8
jz W
;Copy the 1-bpp buffer to the screen (with colors) and clear it
mov dl,0xce ; Graphics Controller
mov ax,0x0305 ; al=5 (GC mode), ah=read mode 0, write mode 3
out dx,ax
xor di,di
mov bx,480
B:xor ax,ax
imul cx,bx,127
add si,cx ; si = error diffusion
adc al,9 ; colors: 10 cyan, 11 green, 14 yellow
add si,cx
adc al,0
cmp al,9
jne E
mov al,14
E:xchg ah,al
out dx,ax ; al=0 (GC set/reset), ah=color
mov cx,640/8
C:salc
xchg al,[di+SCREEN_OFFSET]
stosb
;e2 f8
loop C
ZOOM: ; 0xf84b = 19448
;4b
dec bx
jnz B
;Wireframe sphere tesselations: 12x6 10x5 8x4 6x3 4x2
mov dx,6
T:imul cx,dx,2
U:mov bp,dx
V:call S ; bx,di = point(cx,bp) of a dx-tesselated sphere
mov si,di
xchg ax,bx ; -> ax,si
inc bp
call S
call L ; draw a line from (bx>>6,di>>6) to (ax>>6,si>>6)
dec bp
inc cx
call S
call L
dec cx
dec bp
jnz V
loop U
dec dx
cmp dx,1
jne T
;Next frame
fiadd word[K44]; 44/(2pi) = 7.0028175 (t is an argument for sincos)
in al,60h ; esc?
cmp al,1
jnz M
; ret ; fallthrough
;Generate a point on a tesselated sphere
S:pusha ; pusha: ax cx dx bx sp bp si di
mov bx,10 ; adr: bx+4 2 0 -2 -4 -6 -8 -10
add bx,sp ; inputs: U R V
; outputs: Y X
fiadd word[bx] ; t+=R: offset animations of different spheres
;Convert spherical coordinates (R=dx,U=cx,V=bp) to 2D Cartesian (bx,di)
fild word[bx+2] ; U t
fldpi
fidiv word[bx]
fmulp ; U*=pi/R t
fsincos ; cU sU t
fld st0 ; cU cU sU t
fild word[bx-6] ; V cU cU sU t
fldpi
fidiv word[bx]
fmulp ; V*=pi/R cU cU sU t
fadd st4 ; V+=t cU cU sU t
fsincos ; cV sV cU cU sU t
fmulp st2,st0 ; sV cU*cV cU sU t
fmulp st2,st0 ; z=cU*cV x=cU*sV y=sU t
fild word[bx]
fmul st3,st0
fmul st2,st0
fmulp st1,st0 ; z*=R x*=R y*=R t
;Rotate in the YZ plane
fld st0
fld st3
fld st5 ; t y z z x y t
fcos
fsub st6 ; T=cos(t)-t y z z x y t
fsincos ; cT sT y z z x y t
fmul st2,st0 ; cT sT cT*y z z x y t
fmulp st3,st0 ; sT cT*y cT*z z x y t
fmul st3,st0 ; sT cT*y cT*z sT*z x y t
fmulp st5,st0 ; cT*y cT*z sT*z x sT*y t
faddp st2,st0 ; cT*z cT*y+sT*z x sT*y t
fsubp st3,st0 ; z=cT*y+sT*z x y=cT*z-sT*y t
fiadd word[DEPTH]
fidivr word[ZOOM-1]; Z=zoom/(z+depth) x y t
fmul st1,st0
fmulp st2,st0 ; X=x/Z Y=y/Z t
fistp word[bx-2] ; saved bx = X
fistp word[bx-10]; saved di = Y
fisub word[bx] ; t-=R
popa
ret
;Draw a line from (ax>>6,si>>6) to (bx>>6,di>>6)
L pusha
sub di,si
sub bx,ax
mov cx,0x3F06 ; ch = iters
sar bx,cl ; bx = (x1-x0) / 64
sar di,cl ; di = (y1-y0) / 64
;Plot a pixel: ax=X si=Y (fixed-point int10.6)
X pusha
sar si,cl
sar ax,cl
imul si,80 ; offset = Y*(screen_width / 8) + X/8
xor al,7 ; 7 is the leftmost pixel from the 8-pixel chunk
bts [si+SCREEN_OFFSET+(240*640 + 320)/8],ax
F popa
add ax,bx ; next pixel
add si,di
N dec ch
jnz X
popa
ret
DEPTH dw 10
K44 dw 44
[ back to the prod ]
