From: Ed Beroset
Subject: Re: Fire effect 1/2
At 23:33 12/27/97, you wrote:
>; If you can get it smaller, mail me please!
Here it is a bit smaller:
-+---
; ---------------------------------------------------------------------------
; Fire effect by Jestyr aka Sam Izzo (taran@alphalink.com.au)
; Written on: 27-12-1997
;
; Compiled with A86 which is why there are lots of db statements: A86 doesn't
; support 80386 instructions. Shouldn't be hard to convert to TASM. I did
; it once, but it was 31 bytes bigger and I got a jump out of range error,
; whereas I didn't get one in A86 (??)
;
; It's fast enough (almost) on my P100. I was aiming to get it fast, decent
; looking, and small. I hope I managed alright :) It's guaranteed to be
; slow on a 386, I dunno how it'll run on a 486, but it should be fine on
; any kind of Pentium. If you can get it smaller, mail me please!
;
; It doesn't check for free memory, so make sure you have about 130k free. I
; think most people should be able to manage that! There are also no checks
; for 80386 and VGA! You were warned =P
;
; It should be 242 bytes with A86.
;
; Oh, and hit escape to quit!
;
; Tweaked by Ed Beroset on Mon 12-29-1997
; changed to TASM/MASM syntax, created some subroutines, and generally
; tightened things to shave it to 222 bytes.
;
; ---------------------------------------------------------------------------
.model tiny
stksize = 200h
.code
.386
org 100h
start proc
; move stack pointer
stkend = (stkptr - start) + stksize + 100h
mov sp, stkend
; resize block so we can allocate some memory
mov bx, (stkend + 100h) / 10h
mov ah, 4ah
int 21h
call callocbuff
mov fs,bx ; first buffer
call callocbuff ; second buffer (es = ptr)
; set vid mode to 320x200x256
mov al, 13h ; ah is already 0
int 10h
; set up palette
; here's some pseudocode for how i set the palette:
; for i = 0 to 63
; begin ; al ah bh bl
; setpal(i, i, 0, 0)
; setpal(i+64, 63, i, 0)
; setpal(i+128, 63, 63, i)
; setpal(i+192, 63, 63, 63)
; end
mov cl, 03fh ; ch is already 0
mov di,offset setpal
@palloop1:
mov ah,cl
mov al,cl
xor bx,bx
call di
mov ah,3fh
mov bh,cl
call di
mov bh,3fh
mov bl,cl
call di
mov bl,3fh
call di
dec cx
jns @palloop1
push 0a000h
pop gs
; main loop - generate hotspots, average the buffer, etc
@mainlooper:
push es ; point ds at buffer 2
pop ds
mov cx, 378d ; change this to draw more hotspots, 351 looks good
mov bl, 0ffh
; draw hotspots at random positions on the bottom row of the gs buf
@randlooper:
in al, 40h ; get a value from the timer to use as a random number
add ax, bp ; bp is the seed
add bp, ax ; fiddle with it
; divide it a bit so it doesn't go over 320
mov di, ax
sar ax, 8
sar di, 6
add di, ax
mov [di+63680d],bl ; 199*320 - bottom of buffer
dec cx
jnz @randlooper
mov di, 63999d
; es,ds -> virscr
; fs -> scr2
; gs -> video memory
; now the main loop which does the averaging
@loop:
; add up our four pixels..
; i use buf[x, y]+buf[x, y-1]+buf[x-1, y]+buf[x+1, y]
; this looks quite good, but you can do whatever you want, really
mov si,di
sub si,320
mov bl, [di]
mov ax, bx
mov bl, [si] ; di-320
add ax, bx
mov bl, [di-1]
add ax, bx
mov bl, [di+1]
add ax, bx
sar ax, 2 ; ..divide by four..
; ..and al contains the averaged value. we'll make it decay a bit
cmp al, 1
jle @nodecay
sub al, 2
@nodecay:
; draw to fs buffer
mov fs:[si], al ; di-320
cmp di, 62719d ; (200-4)*320-1 - don't draw the bottom four lines
ja @nodraw
mov gs:[si], al ; draw to video memory
@nodraw:
dec di
cmp di, 16000d ; no use averaging the whole screen if the fire never
ja @loop ; gets that high
; blit buffer at fs to buffer at ds (ds = es)
mov cx, di ; when we come out of the averaging loop, di = 16000d
xor di, di
push fs
pop ds
xor si, si
rep movsd ; 32-bit move - rep movsd = rep movsw with db 66h prefix
; check for escape (scancode of 1)
in al, 60h
dec al
jnz @mainlooper
; free previously allocated memory
; es = first block
mov ah, 49h
int 21h
push fs ; fs = second block
pop es
mov ah, 49h
int 21h
; back to text mode
mov ax, 0003h
int 10h
mov ah,4ch
int 21h ; terminate program
start endp
callocbuff proc
; allocate some memory
mov ah, 48h
mov bx, 4040d
int 21h
mov bx,ax
; zero it
mov es, ax
xor di, di
mov cx, 32320d
xor ax, ax
rep stosw
ret
callocbuff endp
setpal proc
push ax
mov dx, 03c8h
out dx, al ; out 3c8,i
inc dx
mov al, ah
out dx, al ; out 3c9,i
mov al, bh
out dx, al ; out 3c9,0
mov al, bl
out dx, al ; out 3c9,0
pop ax
add al,40h ; set for next round
ret
setpal endp
stkptr label byte
end start
-+---
Ed
-!-
---
---------------
* Origin: The Circuit! Board * Spokane * (1:346/100)
|