home *** CD-ROM | disk | FTP | other *** search
- ;
- ; *** Listing 11-33 ***
- ;
- ; Illustrates animation based on exclusive-oring.
- ; Animates 10 images at once.
- ; Not a general animation implementation, but rather an
- ; example of the strengths and weaknesses of exclusive-or
- ; 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 <64,4,8,4>
- Image <144,0,56,2>
- Image <224,-4,104,0>
- Image <64,4,152,-2>
- Image <144,0,8,-4>
- Image <224,-4,56,-2>
- Image <64,4,104,0>
- Image <144,0,152,2>
- Image <224,-4,8,4>
- Image <64,4,56,2>
- ImagesEnd label Image
- ;
- ; Pixel pattern for the one image this program draws,
- ; a 32x32 3-color square.
- ;
- TheImage label byte
- rept 32
- dw 0ffffh, 05555h, 0aaaah, 0ffffh
- endm
- IMAGE_HEIGHT equ 32 ;# of rows in the image
- IMAGE_WIDTH equ 8 ;# of bytes across the image
- ;
- ; Exclusive-ors 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
- ;
- XorImage:
- 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 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 XOR
- ; the image a word at a time
- XorRowLoop:
- mov cx,bp ;# of words to draw per row of the
- ; image
- XorColumnLoopEvenRows:
- lodsw ;next word of the image pattern
- xor es:[di],ax ;XOR the next word of the
- ; image into the screen
- inc di ;point to the next word in display
- inc di ; memory
- loop XorColumnLoopEvenRows
- 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
- XorColumnLoopOddRows:
- lodsw ;next word of the image pattern
- xor es:[di],ax ;XOR the next word of the
- ; image into the screen
- inc di ;point to the next word in display
- inc di ; memory
- loop XorColumnLoopOddRows
- sub di,BANK_OFFSET-SCREEN_WIDTH+IMAGE_WIDTH
- ;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 XorRowLoop
- 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
- ;
- ; Draw all the images initially.
- ;
- mov bx,offset Images ;list of images
- InitialDrawLoop:
- mov cx,[bx+XCoord] ;X coordinate
- mov dx,[bx+YCoord] ;Y coordinate
- call XorImage ;draw this image
- add bx,size Image ;point to next image
- cmp bx,offset ImagesEnd
- jb InitialDrawLoop ;draw next image, if
- ; there is one
- ;
- ; Erase, move, and redraw each image in turn REPETITIONS
- ; times.
- ;
- MainMoveAndDrawLoop:
- mov bx,offset Images ;list of images
- ImageMoveLoop:
- mov cx,[bx+XCoord] ;X coordinate
- mov dx,[bx+YCoord] ;Y coordinate
- call XorImage ;erase this image (it's
- ; already drawn at this
- ; location, so this XOR
- ; erases it)
- mov cx,[bx+XCoord] ;X coordinate
- cmp cx,4 ;at left edge?
- ja CheckRightMargin ;no
- neg [bx+XInc] ;yes, so bounce
- CheckRightMargin:
- cmp cx,284 ;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,4 ;at top edge?
- ja CheckBottomMargin ;no
- neg [bx+YInc] ;yes, so bounce
- CheckBottomMargin:
- cmp dx,164 ;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 XorImage ;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