pouët.net

Kaustika by Řrřola [web]

; ((  (   (   ((  (  ((( )))))) ) ))  )   ) a 256-byte intro
; (( (   (((  ((  ( ((     ))  )) )) )   ))) by rrrola
; ((((  (__(( ((  (   ((   ))  )) ))))  )__)) rrrola@gmail.com
; (( (( (   (( (((  (((    ))  )) )) )) )   )) greets to every poolgoer

org 100h     ; assume ah=0 dx=cs cs<=5700
  mov al,13h ; graphics mode

  add dh,al  ; claim a few 64kB segments
  mov ds,dx  ; Pos (s16) - 160x200
  add dh,al
  mov es,dx  ; Old Pos (s16) - 160x200
  add dh,al
  mov fs,dx  ; Caustics (u8) - 320x200
  push 0xa000
  pop gs     ; Screen

; Palette: clamped blue gradient (#55aaff).
  cwd  ; dx=0
P int 10h
  mov ax,0x1010 ; set palette color: bl=index dh=R ch=G cl=B
  add dx,0x30   ; slow red
  imul cx,dx,2
  cmp ch,63
  jna PH
  mov ch,63     ; 2x faster green (clamped to 63)
PH:
  mov cl,ch
  add cl,dh
  cmp cl,63
  jna PL
  mov cl,63     ; 3x faster blue (clamped to 63)
PL:
  inc bl
  jnz P

; Zero the position buffers.
  xor si,si
I mov [si],bl    ; Pos=0
  mov [es:si],bl ; Old=0
  inc si
  jnz I
  
  mov cx,0x503 ; used for easier constants

; dx,bp=time si=0
M:

; Add a new drop. Randomize the interval a little.
  push dx
  and dh,cl
  inc dh
  sub bp,dx  ; bp -= (dx & 0x3ff) + 0x100
  pop dx
  jnc DINC   ; if it overflows, add a new drop
  imul di,dx,2
  add word[di],0x1500
  imul dx,85
  inc dx
DINC:

  pusha

; Classic water ripple.
;      2/3
; 1/3 -old  1/3
;      2/3
O:
  mov ax,[si+320]
  add ax,[si-320]
  add ax,ax
  add ax,[si+2]
  add ax,[si-2]
  mov dx,65535/3
  imul dx
  sub dx,[es:si]

  mov bx,dx ; fade out a little
  sar dx,12
  sub bx,dx
  mov [es:si],bx

  mov di,bx ; dy for caustics
  sub di,[es:si-320]
  sar di,2
  imul di,320
  add di,si

  push bx   ; dx for caustics
  sub bx,[es:si-2]
  sar bx,2
  add byte[fs:bx+di],ch
  add byte[fs:bx+di+1],ch

  pop bx    ; old dx for caustics
  sub bx,[si-2]
  sar bx,2
  add byte[fs:bx+di],ch
  add byte[fs:bx+di+1],ch
  
  inc si
  inc si
  jnz O

; Swap buffers.
  push ds
  push es
  pop ds
  pop es

; Draw two pixels at a time. ah = previous pixel
  xor ax,ax
S:
  mov bx,[si+2]  
  mov dx,[si]
  add dx,bx      ; main ripple shading
  shr dx,cl

  sub bx,[si]

  sar bx,cl
  sub bx,si
  and bx,32      ; warped vertical background stripes

  fs lodsb       ; add:
  add al,[fs:si] ; - caustics
  add al,48      ; - ambient
  add al,dl      ; - ripple shading
  add al,bl      ; - warped background

  mov [gs:si],al
  
  xchg al,ah     ; odd pixels are the average of their neighbors
  add al,ah
  rcr al,1
  mov [gs:si-1],al

  inc si
  jnz S

; Fade out caustics.
F shr byte[fs:si],1
  inc si
  jnz F

; Wait for retrace end.
  mov dx,0x3da
V in al,dx
  test al,8
  jnz V
W in al,dx
  test al,8
  jz W

  popa

; ESC check
  in al,60h
  dec al
  jnz M
  
; Text mode
  mov ax,3
  int 10h
  ret