home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Hack-Phreak Scene Programs
/
cleanhpvac.zip
/
cleanhpvac
/
SKY.ZIP
/
SUBDIV.ASM
< prev
next >
Wrap
Assembly Source File
|
1996-02-14
|
5KB
|
230 lines
;----------------------------------------------------------------------
; Subdivide(Map:Pointer;Start,Side:word): Fractal plasma routine.
;
; Map points to a 65536-byte array initialised to all 255's.
; Start is the coords of the TL corner (Y,X in 8.8 format)
; Length is the side length of the square
;
; Smooth(Map:Pointer) Smooths a map
;
; This code is Copyright (C) 1996 Mark Mackey. Use, modification,
; and redistribution of this code is freely permitted, provided that
; the original author is acknowledged.
;
;----------------------------------------------------------------------
.model small,pascal
.386
EXTRN Randseed:DWORD
.CODE
@Random MACRO
; Returns a random number in ax
; Kills ax,dx,flags
mov eax,[randseed]
mov edx,000041a7h
mul edx
and eax,07FFFFFFFh
mov [randseed],eax
shr eax,8
endm
@ScaledRandom MACRO scale
; Returns a random number in dx between -scale and scale
; Kills ax,dx,flags
@Random
mov dl,scale
xor dh,dh
shl dx,2
imul dx
endm
@AddRandom MACRO
; Input: dx = raw value cl=size of random displacement
; Output al = clipped final value
; Modifies dx,ax
push dx ; average of tl and tr corners of square
@ScaledRandom cl
pop ax
add ax,dx ; add random displacement
jg $+5 ; jump to NotTooLow if greater than zero
mov ax,1
;NotTooLow
cmp ax,0feh
jbe $+4 ; jump to NotTooHigh if less than 255
mov al,0feh
;NotTooHigh
endm
PUBLIC Subdivide,Smooth
Subdivide proc near Pascal Map:FAR PTR, Start:WORD, Side: WORD
pusha
les di,[Map]
cmp di,0
jne @Finished ;need di=0 (ie Map is whole segment)
@Random ;initialise RNG
mov cx,[Side]
shr cx,1 ;cl holds Side/2
mov ax,[Start] ;ax holds map x,y position: assumes width=256
mov di,ax
mov dl,es:[di] ;dl holds value at tl corner
mov bx,ax
add bl,cl
mov di,bx
add bl,cl ;ax=tl corner,di=top centre, bx=tr corner
cmp byte ptr es:[di],0FFh
jne @TopOK
xor dh,dh
add dl,es:[bx]
adc dh,0
shr dx,1 ; average of tl and tr corners of square
@AddRandom
mov es:[di],al ; midpoint of top of square done!
@TopOK:
mov dl,es:[bx]
add bh,cl
mov di,bx
add bh,cl ;di=right centre, bx=br corner
cmp byte ptr es:[di],0FFh
jnz @RightOK
xor dh,dh
add dl,es:[bx]
adc dh,0
shr dx,1
@AddRandom
mov es:[di],al
@RightOK:
mov dl,es:[bx]
sub bl,cl
mov di,bx
sub bl,cl ;di=bottom centre, bx=bl corner
cmp byte ptr es:[di],0FFh
jnz @BottomOK
xor dh,dh
add dl,es:[bx]
adc dh,0
shr dx,1
@AddRandom
mov es:[di],al
@BottomOK:
mov dl,es:[bx]
sub bh,cl
mov di,bx
sub bh,cl ;di=left centre, bx=tl corner
cmp byte ptr es:[di],0FFh
jnz @LeftOK
xor dh,dh
add dl,es:[bx]
adc dh,0
shr dx,1
@AddRandom
mov es:[di],al
@LeftOK:
xor dh,dh ; Now do centre of square
mov dl,es:[bx] ; tl corner
add bl,cl
add bl,cl
add dl,es:[bx] ; tr corner
adc dh,0
add bh,cl
add bh,cl
add dl,es:[bx] ; br corner
adc dh,0
sub bl,cl
sub bl,cl
add dl,es:[bx] ; bl corner
adc dh,0
shr dx,2 ; divide by 4
sub bh,cl
add bl,cl ; bx points to centre of square
@AddRandom
mov es:[bx],al
@MiddleOK:
cmp cl,1
jbe @Finished
mov ch,0
push es
push 0000h
push bx ;centrepoint: br square
push cx
call Subdivide
push es
push 0000h
sub bl,cl ;bl square
push bx
push cx
call Subdivide
push es
push 0000h
sub bh,cl ;tl square
push bx
push cx
call Subdivide
push es
push 0000h
add bl,cl ;tr square
push bx
push cx
call Subdivide
@Finished:
popa
ret
Subdivide endp
Smooth proc near Pascal MapToSmooth:FAR PTR,Shift:WORD
les si,[MapToSmooth]
xor bx,bx
@Loop:
mov al,es:[bx]
xor ah,ah
add al,es:[bx+1]
adc ah,0
add al,es:[bx-1]
adc ah,0
add al,es:[bx+256]
adc ah,0
shr ax,2
mov es:[bx],al
add bx,1
jnc @Loop
xor bx,bx
mov dx,[Shift]
@Loop2:
movzx ax,es:[bx]
add ax,dx
cmp ax,0
jge @NotNeg
mov ax,0
jmp @OK
@NotNeg:
cmp ax,0feh
jle @OK
mov al,0feh
@OK:
mov es:[bx],al
add bx,1
jnc @Loop2
ret
Smooth endp
end