home *** CD-ROM | disk | FTP | other *** search
- ;
- ; *** 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