Category : Files from Magazines
Archive   : PJ72.ZIP
Filename : ANIMATE.ASM

 
Output of file : ANIMATE.ASM contained in archive : PJ72.ZIP

;
; *** Listing 1 ***
;
; Program to demonstrate bit-plane animation. Performs
; flicker-free animation with image transparency and
; image precedence across four distinct planes, with
; 13 32x32 images kept in motion at once.
;
;
; Set to higher values to slow down on faster computers.
; 0 is fine for a PC. 500 is a reasonable setting for an AT.
; Slowing animation further allows a good look at
; transparency and the lack of flicker and color effects
; when images cross.
;
SLOWDOWN equ 0
;
; Plane selects for the four colors we're using.
;
RED equ 01h
GREEN equ 02h
BLUE equ 04h
WHITE equ 08h
;
VGA_SEGMENT equ 0a000h ;mode 10h display memory
; segment
SC_INDEX equ 3c4h ;Sequence Controller Index
; register
MAP_MASK equ 2 ;Map Mask register index in
; Sequence Controller
SCREEN_WIDTH equ 80 ;# of bytes across screen
SCREEN_HEIGHT equ 350 ;# of scan lines on screen
WORD_OUTS_OK equ 1 ;set to 0 to assemble for
; computers that can't
; handle word outs to
; indexed VGA regs
;
stack segment para stack 'STACK'
db 512 dup (?)
stack ends
;
; Complete info about one object that we're animating.
;
ObjectStructure struc
Delay dw ? ;used to delay for n passes
; throught the loop to
; control animation speed
BaseDelay dw ? ;reset value for Delay
Image dw ? ;pointer to drawing info
; for object
XCoord dw ? ;object X location in pixels
XInc dw ? ;# of pixels to increment
; location by in the X
; direction on each move
XLeftLimit dw ? ;left limit of X motion
XRightLimit dw ? ;right limit of X motion
YCoord dw ? ;object Y location in pixels
YInc dw ? ;# of pixels to increment
; location by in the Y
; direction on each move
YTopLimit dw ? ;top limit of Y motion
YBottomLimit dw ? ;bottom limit of Y motion
PlaneSelect db ? ;mask to select plane to
; which object is drawn
db ? ;to make an even # of words
; long, for better 286
; performance (keeps the
; following structure
; word-aligned)
ObjectStructure ends
;
Data segment word 'DATA'
;
; Palette settings to give plane 0 precedence, followed by
; planes 1, 2, and 3. Plane 3 has the lowest precedence (is
; obscured by any other plane), while plane 0 has the
; highest precedence (displays in front of any other plane).
;
Colors db 000h ;background color=black
db 03ch ;plane 0 only=red
db 03ah ;plane 1 only=green
db 03ch ;planes 0&1=red (plane 0 priority)
db 039h ;plane 2 only=blue
db 03ch ;planes 0&2=red (plane 0 priority)
db 03ah ;planes 1&2=green (plane 1 priority)
db 03ch ;planes 0&1&2=red (plane 0 priority)
db 03fh ;plane 3 only=white
db 03ch ;planes 0&3=red (plane 0 priority)
db 03ah ;planes 1&3=green (plane 1 priority)
db 03ch ;planes 0&1&3=red (plane 0 priority)
db 039h ;planes 2&3=blue (plane 2 priority)
db 03ch ;planes 0&2&3=red (plane 0 priority)
db 03ah ;planes 1&2&3=green (plane 1 priority)
db 03ch ;planes 0&1&2&3=red (plane 0 priority)
db 000h ;border color=black
;
; Image of a hollow square.
; There's an 8-pixel-wide blank border around all edges
; so that the image erases the old version of itself as
; it's moved and redrawn.
;
Square label byte
dw 48,6 ;height in pixels, width in bytes
rept 8
db 0,0,0,0,0,0 ;top blank border
endm
.radix 2
db 0,11111111,11111111,11111111,11111111,0
db 0,11111111,11111111,11111111,11111111,0
db 0,11111111,11111111,11111111,11111111,0
db 0,11111111,11111111,11111111,11111111,0
db 0,11111111,11111111,11111111,11111111,0
db 0,11111111,11111111,11111111,11111111,0
db 0,11111111,11111111,11111111,11111111,0
db 0,11111111,11111111,11111111,11111111,0
db 0,11111111,00000000,00000000,11111111,0
db 0,11111111,00000000,00000000,11111111,0
db 0,11111111,00000000,00000000,11111111,0
db 0,11111111,00000000,00000000,11111111,0
db 0,11111111,00000000,00000000,11111111,0
db 0,11111111,00000000,00000000,11111111,0
db 0,11111111,00000000,00000000,11111111,0
db 0,11111111,00000000,00000000,11111111,0
db 0,11111111,00000000,00000000,11111111,0
db 0,11111111,00000000,00000000,11111111,0
db 0,11111111,00000000,00000000,11111111,0
db 0,11111111,00000000,00000000,11111111,0
db 0,11111111,00000000,00000000,11111111,0
db 0,11111111,00000000,00000000,11111111,0
db 0,11111111,00000000,00000000,11111111,0
db 0,11111111,00000000,00000000,11111111,0
db 0,11111111,11111111,11111111,11111111,0
db 0,11111111,11111111,11111111,11111111,0
db 0,11111111,11111111,11111111,11111111,0
db 0,11111111,11111111,11111111,11111111,0
db 0,11111111,11111111,11111111,11111111,0
db 0,11111111,11111111,11111111,11111111,0
db 0,11111111,11111111,11111111,11111111,0
db 0,11111111,11111111,11111111,11111111,0
.radix 10
rept 8
db 0,0,0,0,0,0 ;bottom blank border
endm
;
; Image of a hollow diamond with a smaller diamond in the
; middle.
; There's an 8-pixel-wide blank border around all edges
; so that the image erases the old version of itself as
; it's moved and redrawn.
;
Diamond label byte
dw 48,6 ;height in pixels, width in bytes
rept 8
db 0,0,0,0,0,0 ;top blank border
endm
.radix 2
db 0,00000000,00000001,10000000,00000000,0
db 0,00000000,00000011,11000000,00000000,0
db 0,00000000,00000111,11100000,00000000,0
db 0,00000000,00001111,11110000,00000000,0
db 0,00000000,00011111,11111000,00000000,0
db 0,00000000,00111110,01111100,00000000,0
db 0,00000000,01111100,00111110,00000000,0
db 0,00000000,11111000,00011111,00000000,0
db 0,00000001,11110000,00001111,10000000,0
db 0,00000011,11100000,00000111,11000000,0
db 0,00000111,11000000,00000011,11100000,0
db 0,00001111,10000001,10000001,11110000,0
db 0,00011111,00000011,11000000,11111000,0
db 0,00111110,00000111,11100000,01111100,0
db 0,01111100,00001111,11110000,00111110,0
db 0,11111000,00011111,11111000,00011111,0
db 0,11111000,00011111,11111000,00011111,0
db 0,01111100,00001111,11110000,00111110,0
db 0,00111110,00000111,11100000,01111100,0
db 0,00011111,00000011,11000000,11111000,0
db 0,00001111,10000001,10000001,11110000,0
db 0,00000111,11000000,00000011,11100000,0
db 0,00000011,11100000,00000111,11000000,0
db 0,00000001,11110000,00001111,10000000,0
db 0,00000000,11111000,00011111,00000000,0
db 0,00000000,01111100,00111110,00000000,0
db 0,00000000,00111110,01111100,00000000,0
db 0,00000000,00011111,11111000,00000000,0
db 0,00000000,00001111,11110000,00000000,0
db 0,00000000,00000111,11100000,00000000,0
db 0,00000000,00000011,11000000,00000000,0
db 0,00000000,00000001,10000000,00000000,0
.radix 10
rept 8
db 0,0,0,0,0,0 ;bottom blank border
endm
;
; List of objects to animate.
;
even ;word-align for better 286 performance
;
ObjectList label ObjectStructure
ObjectStructure <1,21,Diamond,88,8,80,512,16,0,0,350,RED>
ObjectStructure <1,15,Square,296,8,112,480,144,0,0,350,RED>
ObjectStructure <1,23,Diamond,88,8,80,512,256,0,0,350,RED>
ObjectStructure <1,13,Square,120,0,0,640,144,4,0,280,BLUE>
ObjectStructure <1,11,Diamond,208,0,0,640,144,4,0,280,BLUE>
ObjectStructure <1,8,Square,296,0,0,640,144,4,0,288,BLUE>
ObjectStructure <1,9,Diamond,384,0,0,640,144,4,0,288,BLUE>
ObjectStructure <1,14,Square,472,0,0,640,144,4,0,280,BLUE>
ObjectStructure <1,8,Diamond,200,8,0,576,48,6,0,280,GREEN>
ObjectStructure <1,8,Square,248,8,0,576,96,6,0,280,GREEN>
ObjectStructure <1,8,Diamond,296,8,0,576,144,6,0,280,GREEN>
ObjectStructure <1,8,Square,344,8,0,576,192,6,0,280,GREEN>
ObjectStructure <1,8,Diamond,392,8,0,576,240,6,0,280,GREEN>
ObjectListEnd label ObjectStructure
;
Data ends
;
; Macro to output a word value to a port.
;
OUT_WORD macro
if WORD_OUTS_OK
out dx,ax
else
out dx,al
inc dx
xchg ah,al
out dx,al
dec dx
xchg ah,al
endif
endm
;
; Macro to output a constant value to an indexed VGA
; register.
;
CONSTANT_TO_INDEXED_REGISTER macro ADDRESS, INDEX, VALUE
mov dx,ADDRESS
mov ax,(VALUE shl 8) + INDEX
OUT_WORD
endm
;
Code segment
assume cs:Code, ds:Data
Start proc near
cld
mov ax,Data
mov ds,ax
;
; Set 640x350 16-color mode.
;
mov ax,0010h ;AH=0 means select mode
;AL=10h means select
; mode 10h
int 10h ;BIOS video interrupt
;
; Set the palette up to provide bit-plane precedence. If
; planes 0 & 1 overlap, the plane 0 color will be shown;
; if planes 1 & 2 overlap, the plane 1 color will be
; shown; and so on.
;
mov ax,(10h shl 8) + 2 ;AH = 10h means
; set palette
; registers fn
;AL = 2 means set
; all palette
; registers
push ds ;ES:DX points to
pop es ; the palette
mov dx,offset Colors ; settings
int 10h ;call the BIOS to
; set the palette
;
; Draw the static backdrop in plane 3. All the moving images
; will appear to be in front of this backdrop, since plane 3
; has the lowest precedence the way the palette is set up.
;
CONSTANT_TO_INDEXED_REGISTER SC_INDEX, MAP_MASK, 08h
;allow data to go to
; plane 3 only
;
; Point ES to display memory for the rest of the program.
;
mov ax,VGA_SEGMENT
mov es,ax
;
sub di,di
mov bp,SCREEN_HEIGHT/16 ;fill in the screen
; 16 lines at a time
BackdropBlockLoop:
call DrawGridCross ;draw a cross piece
call DrawGridVert ;draw the rest of a
; 15-high block
dec bp
jnz BackdropBlockLoop
call DrawGridCross ;bottom line of grid
;
; Start animating!
;
AnimationLoop:
mov bx,offset ObjectList ;point to the first
; object in the list
;
; For each object, see if it's time to move and draw that
; object.
;
ObjectLoop:
;
; See if it's time to move this object.
;
dec [bx+Delay] ;count down delay
jnz DoNextObject ;still delaying-don't move
mov ax,[bx+BaseDelay]
mov [bx+Delay],ax ;reset delay for next time
;
; Select the plane that this object will be drawn in.
;
mov dx,SC_INDEX
mov ah,[bx+PlaneSelect]
mov al,MAP_MASK
OUT_WORD
;
; Advance the X coordinate, reversing direction if either
; of the X margins has been reached.
;
mov cx,[bx+XCoord] ;current X location
cmp cx,[bx+XLeftLimit] ;at left limit?
ja CheckXRightLimit ;no
neg [bx+XInc] ;yes-reverse
CheckXRightLimit:
cmp cx,[bx+XRightLimit] ;at right limit?
jb SetNewX ;no
neg [bx+XInc] ;yes-reverse
SetNewX:
add cx,[bx+XInc] ;move the X coord
mov [bx+XCoord],cx ; & save it
;
; Advance the Y coordinate, reversing direction if either
; of the Y margins has been reached.
;
mov dx,[bx+YCoord] ;current Y location
cmp dx,[bx+YTopLimit] ;at top limit?
ja CheckYBottomLimit ;no
neg [bx+YInc] ;yes-reverse
CheckYBottomLimit:
cmp dx,[bx+YBottomLimit] ;at bottom limit?
jb SetNewY ;no
neg [bx+YInc] ;yes-reverse
SetNewY:
add dx,[bx+YInc] ;move the Y coord
mov [bx+YCoord],dx ; & save it
;
; Draw at the new location. Because of the plane select
; above, only one plane will be affected.
;
mov si,[bx+Image] ;point to the
; object's image
; info
call DrawObject
;
; Point to the next object in the list until we run out of
; objects.
;
DoNextObject:
add bx,size ObjectStructure
cmp bx,offset ObjectListEnd
jb ObjectLoop
;
; Delay as specified to slow things down.
;
if SLOWDOWN
mov cx,SLOWDOWN
DelayLoop:
loop DelayLoop
endif
;
; If a key's been pressed, we're done, otherwise animate
; again.
;
CheckKey:
mov ah,1
int 16h ;is a key waiting?
jz AnimationLoop ;no
sub ah,ah
int 16h ;yes-clear the key & done
;
; Back to text mode.
;
mov ax,0003h ;AL=03h means select
; mode 03h
int 10h
;
; Back to DOS.
;
mov ah,4ch ;DOS terminate function
int 21h ;done
;
Start endp
;
; Draws a single grid cross-element at the display memory
; location pointed to by ES:DI. 1 horizontal line is drawn
; across the screen.
;
; Input: ES:DI points to the address at which to draw
;
; Output: ES:DI points to the address following the
; line drawn
;
; Registers altered: AX, CX, DI
;
DrawGridCross proc near
mov ax,0ffffh ;draw a solid line
mov cx,SCREEN_WIDTH/2-1
rep stosw ;draw all but the rightmost
; edge
mov ax,0080h
stosw ;draw the right edge of the
; grid
ret
DrawGridCross endp
;
; Draws the non-cross part of the grid at the display memory
; location pointed to by ES:DI. 15 scan lines are filled.
;
; Input: ES:DI points to the address at which to draw
;
; Output: ES:DI points to the address following the
; part of the grid drawn
;
; Registers altered: AX, CX, DX, DI
;
DrawGridVert proc near
mov ax,0080h ;pattern for a vertical line
mov dx,15 ;draw 15 scan lines (all of
; a grid block except the
; solid cross line)
BackdropRowLoop:
mov cx,SCREEN_WIDTH/2
rep stosw ;draw this scan line's bit
; of all the vertical lines
; on the screen
dec dx
jnz BackdropRowLoop
ret
DrawGridVert endp
;
; Draw the specified image at the specified location.
; Images are drawn on byte boundaries horizontally, pixel
; boundaries vertically.
; The Map Mask register must already have been set to enable
; access to the desired plane.
;
; Input:
; CX - X coordinate of upper left corner
; DX - Y coordinate of upper left corner
; DS:SI - pointer to draw info for image
; ES - display memory segment
;
; Output: none
;
; Registers altered: AX, CX, DX, SI, DI, BP
;
DrawObject proc near
mov ax,SCREEN_WIDTH
mul dx ;calculate the start offset in
; display memory of the row the
; image will be drawn at
shr cx,1
shr cx,1
shr cx,1 ;divide the X coordinate in pixels
; by 8 to get the X coordinate in
; bytes
add ax,cx ;destination offset in display
; memory for the image
mov di,ax ;point ES:DI to the address to
; which the image will be copied
; in display memory
lodsw
mov dx,ax ;# of lines in the image
lodsw ;# of bytes across the image
mov bp,SCREEN_WIDTH
sub bp,ax ;# of bytes to add to the display
; memory offset after copying a line
; of the image to display memory in
; order to point to the address
; where the next line of the image
; will go in display memory
DrawLoop:
mov cx,ax ;width of the image
rep movsb ;copy the next line of the image
; into display memory
add di,bp ;point to the address at which the
; next line will go in display
; memory
dec dx ;count down the lines of the image
jnz DrawLoop
ret
DrawObject endp
;
Code ends
end Start