home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Equalizer BBS
/
equalizer-bbs-collection_2004.zip
/
equalizer-bbs-collection
/
DEMOSCENE-STUFF
/
HQ_WATER.ZIP
/
SURF.ASM
< prev
next >
Wrap
Assembly Source File
|
1994-08-13
|
5KB
|
195 lines
;
; SURF.ASM // ARM 12/93
;
Ideal
Model TPascal
P286
Radix 10
; Constants:
INCLUDE "meshsize.inc"
DATASEG
EXTRN U : DWord
EXTRN B : DWord
EXTRN CT : Word
EXTRN TOPS : Word
EXTRN DAMP : Byte
CODESEG
PUBLIC UpdateTable;
PUBLIC DrawSurf;
; // UpdateTable : performs one integration step on U[CT]
; Differential equation is: u = a²( u + u )
; tt xx yy
;
; Where a² = tension * gravity / surface_density.
;
; Aproximating second derivatives by central differences:
;
; [ u(t+1)-2u(t)+u(t-1) ] / δt² = a² (u(x+1)+u(x-1)+u(y+1)+u(y-1)-4u) / h²
;
; (where δt = time step, h=δx=δy = mesh resolution
;
; From where u(t+1) may be calculated as:
; ┌ 1 ┐
; u(t+1) = a²δt²/h² │ 1 0 1 │u - u(t-1) + (2-4a²δt²/h²)u
; └ 1 ┘
;
; When a²δt²/h² = ½ last term vanishes, giving:
; ┌ 1 ┐
; u(t+1) = ½ │ 1 0 1 │u - u(t-1)
; └ 1 ┘
;
; This needs only 4 ADD/SUB and one SAR operation per mesh point!
;
; (note that u(t-1,x,y) is only used to calculate u(t+1,x,y) so
; we can use the same array for both t-1 and t+1, needing only
; two arrays, U[0] and U[1])
;
; Dampening is simulated by subtracting 1/2^n of result.
; n=4 gives best-looking result
; n<4 (eg 2 or 3) thicker consistency, waves die out immediately
; n>4 (eg 8 or 12) more fluid, waves die out slowly
;
PROC UpdateTable NEAR
push bp
mov si, [word ptr U]
add si, NY*2 - 4
mov di, si
add si, NX*NY*2
test [CT], 1
jz @@0
xchg si,di
@@0: ; si->next/last, di->this
mov cl, [Damp]
mov dx, NX-2
push ds
mov ax, [word ptr U+2]
mov ds, ax
@@fori:
add si, 4
add di, 4
mov bp, NY-2
@@forj:
add si, 2
add di, 2 ; add up N,S,E,W points :
mov ax, [di-2*NY] ; [ u(t,x-1,y)
add ax, [di+2*NY] ; + u(t,x+1,y)
add ax, [di-2] ; + u(t,x,y-1)
add ax, [di+2] ; + u(t,x,y+1) ]
sar ax,1 ; /2
sub ax, [si] ; -u(t-1,x,y)
mov bx, ax
sar bx, cl ; subtract 1/16 of result for dampening
sub ax, bx
mov [si],ax ; save result
dec bp
jnz @@forj
dec dx
jnz @@fori
pop ds
pop bp
ret
ENDP
; // DrawSurf : draws water surface in fake 3D
;
PROC DrawSurf NEAR
P386
push bp
mov si, [word ptr U]
test [CT], 1
jz @@0
add si, NX*NY*2
@@0: ; ds:si -> U[CT]
mov ax, 0a000h
mov es, ax
mov di, 199*320 ; es:di -> Screen[199,0]
mov bx, offset TOPS
mov cx, NX
push gs fs ds
mov ax, ds
mov fs, ax
mov ax, [word ptr B+2]
mov gs, ax
mov ax, [word ptr U+2]
mov ds, ax
@@forX:
push cx
push di
push bx
mov bx,7 ; highest so far
mov bp, 200*(101h)
mov cx, NY
@@forY:
sub bx,8 ; each row is 8 (=1 pixel) higher
mov ax, [si] ; then the last.
mov dx, ax
sub dx, bx
jng @@1 ; not above current highest
or ax, 0007 ; round to 7 + a multiple of 8
mov bx, ax
; dec dx/sar dx,3/.../dec dx/jge @2 (dx+1 times)
@@2:
mov [es:di],bp
sub di,320 ; point to next row, same column
sub dx,8
jg @@2 ; (you wouldn't believe how much
; slower LOOP is on a 486!)
@@1:
add si,2 ; point to next column, U[CT,X,Y+1]
sub bp, 0101h ; dim color one notch
dec cx
jnz @@forY ; LOOPs suck!
pop bx
mov ax, [fs:bx] ; get last top of column address
mov [fs:bx], di ; ...and save current one for next time
add bx,2 ; (update ptr for next col)
@@3:
cmp ax, di
jae @@4
mov bp, [gs:di]
mov [es:di],bp ; if this column is lower than the
sub di, 320 ; last one, clear extra rows w/ background
jmp @@3
@@4:
pop di ; fetch addr of row 199
add di,2 ; skip to next column
pop cx ; fetch counter
dec cx
jnz @@forX ; did I mention...? ;-)
pop ds fs gs
pop bp
P286
ret
ENDP
END