home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Graphics Programming Black Book (Special Edition)
/
BlackBook.bin
/
disk1
/
zenasmlg
/
zen_list.exe
/
LST11-34.ASM
< prev
next >
Wrap
Assembly Source File
|
1990-02-15
|
7KB
|
244 lines
;
; *** Listing 11-34 ***
;
; Illustrates animation based on block moves.
; Animates 10 images at once.
; Not a general animation implementation, but rather an
; example of the strengths and weaknesses of block-move
; based animation.
;
; Make with LZTIME.BAT, since this program is too long to be
; handled by the precision Zen timer.
;
jmp Skip
;
DELAY equ 0 ;set to higher values to
; slow down for closer
; observation
REPETITIONS equ 500 ;# of times to move and
; redraw the images
DISPLAY_SEGMENT equ 0b800h ;display memory segment
; in 320x200 4-color
; graphics mode
SCREEN_WIDTH equ 80 ;# of bytes per scan line
BANK_OFFSET equ 2000h ;offset from the bank
; containing the even-
; numbered lines on the
; screen to the bank
; containing the odd-
; numbered lines
;
; Used to count down # of times images are moved.
;
RepCount dw REPETITIONS
;
; Complete info about one image that we're animating.
;
Image struc
XCoord dw ? ;image X location in pixels
XInc dw ? ;# of pixels to increment
; location by in the X
; direction on each move
YCoord dw ? ;image Y location in pixels
YInc dw ? ;# of pixels to increment
; location by in the Y
; direction on each move
Image ends
;
; List of images to animate.
;
Images label Image
Image <60,4,4,4>
Image <140,0,52,2>
Image <220,-4,100,0>
Image <60,4,148,-2>
Image <140,0,4,-4>
Image <220,-4,52,-2>
Image <60,4,100,0>
Image <140,0,148,2>
Image <220,-4,4,4>
Image <60,4,52,2>
ImagesEnd label Image
;
; Pixel pattern for the one image this program draws,
; a 32x32 3-color square. There's a 4-pixel-wide blank
; fringe around each image, which makes sure the image at
; the old location is erased by the drawing of the image at
; the new location.
;
TheImage label byte
rept 4
dw 5 dup (0) ;top blank fringe
endm
rept 32
db 00h ;left blank fringe
dw 0ffffh, 05555h, 0aaaah, 0ffffh
db 00h ;right blank fringe
endm
rept 4
dw 5 dup (0) ;bottom blank fringe
endm
IMAGE_HEIGHT equ 40 ;# of rows in the image
; (including blank fringe)
IMAGE_WIDTH equ 10 ;# of bytes across the image
; (including blank fringe)
;
; Block-move draws the image of a 3-color square at the
; specified screen location. Assumes images start on
; even-numbered scan lines and are an even number of
; scan lines high. Always draws images byte-aligned in
; display memory.
;
; Input:
; CX = X coordinate of upper left corner at which to
; draw image (will be adjusted to nearest
; less-than or equal-to multiple of 4 in order
; to byte-align)
; DX = Y coordinate of upper left corner at which to
; draw image
; ES = display memory segment
;
; Output: none
;
; Registers altered: AX, CX, DX, SI, DI, BP
;
BlockDrawImage:
push bx ;preserve the main loop's pointer
shr dx,1 ;divide the row # by 2 to compensate
; for the 2-bank nature of 320x200
; 4-color mode
mov ax,SCREEN_WIDTH
mul dx ;start offset of top row of image in
; display memory
shr cx,1 ;divide the X coordinate by 4
shr cx,1 ; because there are 4 pixels per
; byte
add ax,cx ;point to the offset at which the
; upper left byte of the image will
; go
mov di,ax
mov si,offset TheImage
;point to the start of the one image
; we always draw
mov ax,BANK_OFFSET-SCREEN_WIDTH+IMAGE_WIDTH
;offset from the end of an odd line
; of the image in display memory to
; the start of the next even line of
; the image
mov bx,BANK_OFFSET-IMAGE_WIDTH
;offset from the end of an even line
; of the image in display memory to
; the start of the next odd line of
; the image
mov dx,IMAGE_HEIGHT/2
;# of even/odd numbered row pairs to
; draw in the image
mov bp,IMAGE_WIDTH/2
;# of words to draw per row of the
; image. Note that IMAGE_WIDTH must
; be an even number since we draw
; the image a word at a time
BlockDrawRowLoop:
mov cx,bp ;# of words to draw per row of the
; image
rep movsw ;draw a whole even row with this one
; repeated instruction
add di,bx ;point to the start of the next
; (odd) row of the image, which is
; in the second bank of display
; memory
mov cx,bp ;# of words to draw per row of the
; image
rep movsw ;draw a whole odd row with this one
; repeated instruction
sub di,ax
;point to the start of the next
; (even) row of the image, which is
; in the first bank of display
; memory
dec dx ;count down the row pairs
jnz BlockDrawRowLoop
pop bx ;restore the main loop's pointer
ret
;
; Main animation program.
;
Skip:
;
; Set the mode to 320x200 4-color graphics mode.
;
mov ax,0004h ;AH=0 is mode select fn
;AL=4 selects mode 4,
; 320x200 4-color mode
int 10h ;invoke the BIOS video
; interrupt to set the mode
;
; Point ES to display memory for the rest of the program.
;
mov ax,DISPLAY_SEGMENT
mov es,ax
;
; We'll always want to count up.
;
cld
;
; Start timing.
;
call ZTimerOn
;
; There's no need to draw all the images initially with
; block-move animation.
;
; Move and redraw each image in turn REPETITIONS times.
; Redrawing automatically erases the image at the old
; location, thanks to the blank fringe.
;
MainMoveAndDrawLoop:
mov bx,offset Images ;list of images
ImageMoveLoop:
mov cx,[bx+XCoord] ;X coordinate
cmp cx,0 ;at left edge?
ja CheckRightMargin ;no
neg [bx+XInc] ;yes, so bounce
CheckRightMargin:
cmp cx,280 ;at right edge?
jb MoveX ;no
neg [bx+XInc] ;yes, so bounce
MoveX:
add cx,[bx+XInc] ;move horizontally
mov [bx+XCoord],cx ;save the new location
mov dx,[bx+YCoord] ;Y coordinate
cmp dx,0 ;at top edge?
ja CheckBottomMargin ;no
neg [bx+YInc] ;yes, so bounce
CheckBottomMargin:
cmp dx,160 ;at bottom edge?
jb MoveY ;no
neg [bx+YInc] ;yes, so bounce
MoveY:
add dx,[bx+YInc] ;move horizontally
mov [bx+YCoord],dx ;save the new location
call BlockDrawImage ;draw the image at its
; new location
add bx,size Image ;point to the next image
cmp bx,offset ImagesEnd
jb ImageMoveLoop ;move next image, if there
; is one
if DELAY
mov cx,DELAY ;slow down as specified
loop $
endif
dec [RepCount] ;animate again?
jnz MainMoveAndDrawLoop ;yes
;
call ZTimerOff ;done timing
;
; Return to text mode.
;
mov ax,0003h ;AH=0 is mode select fn
;AL=3 selects mode 3,
; 80x25 text mode
int 10h ;invoke the BIOS video
; interrupt to set the mode