pouët.net

Go to bottom

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
Go to top