Sluníčko by Řrřola [web]
; \|/ Slunicko ;>=O=< a 256-byte intro by rrrola <rrrola@gmail.com> ; /|\ greets to everyone who's ever got a bad sunburn org 100h ; assume cs<=0x4000 ax=0 sp=di=-2 si=0x100 ; macros to access constants %define w(xx) word[byte bp+si-0x100+xx] %define d(xx) dword[byte bp+si-0x100+xx] push ax ; push zero for "ret" push 0xa000 ; screen segment mov ax,0x4f02 ; set VESA mode ;Run through a few constants. ;ab stosw ; di=0 ;3f aas ;22c2 and al,dl ;b7a3 mov bh,0xa3 ;b783 mov bh,0x83 ;bb0e01 mov bx,0x10e ; mode 320x200 with 65536 colors SMUL equ $-2 ; 1.34 db 0xab,0x3f AMUL equ $-2 ; -40.56 ~ -128/pi (-40.74) db 0x22,0xc2 XMUL equ $-3 ; -2.314e-5 ~ -2.441e-5 (320/256 / (256*200)) db 0xb7 YMUL equ $-2 ; -1.952e-5 ~ -1.953e-5 (1 / (256*200)) db 0xa3,0xb7 CMUL equ $-2 ; -0.004 db 0x83,0xbb dw 0x010e int 10h ; set mode 320x200 with 65536 colors RMUL equ $-1 ; 1808 pop es ; es = screen segment lds bx,[si-3] ; bx = 0, ds = 0x5000 texture segment ;Generate 2D Brownian motion texture ; bx=count si=adr bp,dx,cx=random generator ; similar to baze's texture generator, used in Terén M: T lodsb ; al = top right texel dec bp ; do some pseudorandom stuff ror bp,cl xor dx,bp sar dx,3 adc cx,dx ; ch += random (-16..16) adc ch,al ; ch += top right texel rcr cx,1 mov [si+254],ch ; store texel dec bx jnz T ; loop 512x (65536x on init) pusha ; we'll do more texture generation later mov cx,si ; ch=time (texture offset) xor bp,bp ; bp=0, si=0x100 (nice values) mov si,0x100 ;Pixel loop: di=pixel address if the buffer was 8-bit X mov ax,0xcccd ; convert width 320->65536 (from Tetraskelion) mul di xchg ax,bx ; full 16-bit precision of X mov ax,0x4f05 add bx,ax adc dx,0x9b80 ; center at [100, 159.5]: should be 0x9b804d46 pusha ;{di si bp sp bx dx cx ax} to the stack ; YY Y = [-8-18] ; X X X = [-9-18] ;Is it time to switch the VESA bank? add di,di ; switch when pixel address = 0 jnz D cwd adc dx,dx ; dx=page (0 or 1) xor bx,bx ; bh=0 (set bank), bl=0 (window id) int 10h ; assume 64kB granularity and window at 0xA000 ;Build a (5,6,5)-bit pixel: approximate sRGB with [âR âG âB] D call I ; compute color xor ax,ax inc ax ; ax=1 cx=6 mov cl,6 P fsqrt ;; 29656*[âR âG âB] fimul w(BIG) ; store 15-bit color component (0..7fff) fistp word[bp+si] ; if it's > 0x7fff, clamp to 0x8000 imul bx,[bp+si],2 ; double, set carry if it was > 0x3fff sbb bx,bp ; clip overflow (0x8000*2) to 0xffff xor cl,5^6 ; shift lengths: [5 6 5] shld ax,bx,cl ; rrrrrggggggbbbbb: shift into ax BIG: equ $-1 ; 29656 jnc P ; loop 3x until you've shifted the 1 bit out of ax stosw popa inc di jnz X ; loop 65536x, di=0 popa mov bh,2 ; advance time: the texture cycles every 128 frames ;Exit on ESC in al,60h cbw dec ax jne M ; loop until ESC mov al,3 ; textmode int 0x10 ; use "ret" from below ;Subroutine: compute color. ; using a subroutine saves a byte: +3 call, -4 main loop jumps I fild word[bp-8-18] fmul d(YMUL) fild word[bp-9-18] fmul d(XMUL) ;; x=X/(320*200) y=Y/(256*200) ; y:-1..1 add dh,ch ; texture coords for background: add dh,0x80 ; dl = u = x push dx ; dh = v = y+time ;Polar coordinates (from Polar Beat) fld st1 ;; y x y fpatan ;; a=atan(x/y) y ; a:-Ï..Ï, 0=vertical fld st0 fcos ;; cos(a) a y fdivp st2,st0 ;; a r=y/cos(a) ; r=â(x²+y²) fmul d(AMUL) ;; A=a*-128/Ï r ; A:-128..128 fistp dword[bp+si] mov bl,[bp+si]; bl = u texcoord = A fld st0 ;; 1808/r r ; about 7.06 * 256 / r fidivr w(RMUL) fistp dword[bp+si] mov bh,[bp+si+1] ; t = [bp+si] = bottom bits of R (for later) add bh,ch ; bh = v texcoord = R+time ;Sun fmul st0 fld1 ;; 1-r² fsubrp st1,st0 fmul st0 fmul st0 fmul st0 fmul st0 ;; s=(1-r²)¹ⶠmov cx,2 O fld st0 fmul d(SMUL) ;; R=1.34²*s G=1.34*s B=s loop O ; loop 2x ;Foreground: tunnel with chromatic aberration and interpolation mov cl,3 ; Linear interpolation between v and v+1: F mov al,[bp+si] not al ; al = 1-t mul byte[bx] xchg ax,dx ; dx = (1-t) * tex[u,v] ; 8*8 -> 16bit inc bh ; chromatic aberration - R:v G:v+1 B:v+2 mov al,[bp+si] mul byte[bx] ; ax = t * tex(u,v+1) add ax,dx ; ax = (1-t) * tex[u,v] + t * tex[u,v+1] shr ax,7 ; foreground is 2x brighter than background stc jmp A ; accumulate one color channel, return to R R loop F ; loop 3x ;Background: scrolling clouds pop bx ; bx = background texture coordinates mov cl,3 B dec bh mov al,[bx] ; keep white stars when ah>0 clc ; don't return to R ; Subroutine: accumulate one color channel: [R G B] += [x² xâ´ xâ¸] A mov [bp+si-2],ax fild word[bp+si-2] fmul d(CMUL) ; x = -0.004*ax push cx Q fmul st0 loop Q ; loop 1x for R, 2x for G, 3x for B pop cx faddp fstp st3 ;; cycle: R G B -> G B R -> B R G jc R ; return to R loop B ; loop 3x ret
[ back to the prod ]