pouët.net

Terén by Řrřola [web]

; Terén (Terrain)                                     :
; a 63-byte intro by rrrola <rrrola@gmail.com>       :tt    NN
; greets to everyone who likes hiking         .    :tttttt  NN
;....       .                               ..:.t::tttteeE  NN
;tttt:..:..:..::                        . .t:tttteeRRtteeEE NNtee
;eRttteetReRRtttt: . .               . .:.:teRReRRRRRREENENNNNRee
;RReeRReRRRRRettttttttt..            ..teteeeRRRRRREEEENNENNNNNNN
;EEERRRRRRRRRRRetttttetttttt .   :  .:teeeRRRRRREEEEEENNNNNNNNNNN
;ENERERRERRRRRRReeeeeeeettttttt:tttt.ttRRRRERRREEEEENNNNNNNNNNNNN
;NNEEEEEEREERRRRRRRReReeeeteetetettttteRRREEEEENEENNNNNNNNNNNNNNN

org 100h   ; assume ds<=0x249f ax=bx=0 si=0x100 bp~0x91c

;68 f6 9f
  push 0xa000 - 160/16
;34 13
T xor al,13h
;cd 10
  int 0x10      ; set 320x200 mode
;c5 0c
  lds cx,[si]   ; ds=0x349f: texture segment
;07             ; cx=0xf668: texture seed
  pop es        ; es=0x9ff6: centered screen segment

;Generate a row (256 texels) of non-repeating terrain: use cx,bp
;On init, generate the whole texture (65536 texels)
;- rcl trick from baze's texture generator (Tube, Lattice, Lander)
                  ; ch = left texel
;13 cd  adc cx,bp ; ch += random (-16..16)
;10 c5  adc ch,al ; ch += top right texel, or last pixel (on frame start)
;0c 07  or al,7   ; harmless
  shr cx,1        ; average ch to 0..127; cl,carry = old texel bits
  mov [si+126],ch ; store texel = (left + top right + random + adc) / 2
  rcr bp,cl       ; next random value
  sar bp,3        ; adjust it to (-16..16), mess up the top bits
  lodsb           ; load top right texel, advance si (= time)
  dec bx          ; loop 256 times (65536 on init), si += 256
  loopnz T+1      ; cx-- for more randomness

;Raymarch the terrain, compute the hit distance: don't touch cx,bp
;- mul/imul camera trick from HellMood (Gespensterwald)
R mov ax,0xcccd ; bh=z (depth): 1..127 (0 on frame start)
  mul di        ; dh = unsigned y (0..200), dl = signed x (-128..128)
  mov al,dh
  mul bh        ; ah=y*z (unsigned because y can be > 127)
  xchg ax,dx    ; dh=y*z, al=x
  imul bh       ; ah=x*z (signed), al=fraction(x*z)
  mov bl,ah     ; bl=x*z
  cmp [bx+si],dh; hit if texture[x*z, time + z] <= y*z?
  jb D
  inc bh        ; no hit: z++
  jns R

;Dithering, illusion of light from the right side
D aam 37      ; ah=al/37 ~~ 7*fraction(x*z) to prevent color overflow
  sub ah,bh   ; ah -= z_hit (128..255)
  shr ax,11   ; al=ah/8 (16..31: grayscale), ah=0
  mov bx,256  ; bh=1 (init next depth)
  stosb       ; draw_pixel(al)

;Next pixel (65536 times)
  test di,di
  jnz R

;  sub di,sp   ; compute every 3rd pixel (faster)
;  jc R

;Next frame
  jmp T+1     ; bx: make 256 texels; al=last pixel (16..31)
;  in al,0x60   ; + ESC check
;  dec ax
;  jnz T+1
;  ret