home *** CD-ROM | disk | FTP | other *** search
/ Graphics Programming Black Book (Special Edition) / BlackBook.bin / disk1 / source / chapter43 / l43-1.asm next >
Assembly Source File  |  1997-06-18  |  15KB  |  501 lines

  1. ;
  2. ; *** Listing 28.1 ***
  3. ;
  4. ; Program to demonstrate bit-plane animation. Performs
  5. ; flicker-free animation with image transparency and
  6. ; image precedence across four distinct planes, with
  7. ; 13 32x32 images kept in motion at once.
  8. ;
  9. ; Tested with TASM 4.0 by Jim Mischel 12/16/94.
  10. ;
  11. ; Set to higher values to slow down on faster computers.
  12. ; 0 is fine for a PC. 500 is a reasonable setting for an AT.
  13. ; Slowing animation further allows a good look at
  14. ; transparency and the lack of flicker and color effects
  15. ; when images cross.
  16. ;
  17. SLOWDOWN    equ    10000
  18. ;
  19. ; Plane selects for the four colors we're using.
  20. ;
  21. RED    equ    01h
  22. GREEN    equ    02h
  23. BLUE    equ    04h
  24. WHITE    equ    08h
  25. ;
  26. VGA_SEGMENT    equ    0a000h    ;mode 10h display memory
  27.                 ; segment
  28. SC_INDEX        equ    3c4h    ;Sequence Controller Index
  29.                 ; register
  30. MAP_MASK        equ    2    ;Map Mask register index in
  31.                 ; Sequence Controller
  32. SCREEN_WIDTH    equ    80    ;# of bytes across screen
  33. SCREEN_HEIGHT    equ    350    ;# of scan lines on screen
  34. WORD_OUTS_OK    equ    1    ;set to 0 to assemble for
  35.                 ; computers that can't
  36.                 ; handle word outs to
  37.                 ; indexed VGA regs
  38. ;
  39. stack    segment para stack 'STACK'
  40.     db    512 dup (?)
  41. stack    ends
  42. ;
  43. ; Complete info about one object that we're animating.
  44. ;
  45. ObjectStructure    struc
  46. Delay        dw    ?    ;used to delay for n passes
  47.                 ; throught the loop to
  48.                 ; control animation speed
  49. BaseDelay    dw    ?    ;reset value for Delay
  50. Image        dw    ?    ;pointer to drawing info
  51.                 ; for object
  52. XCoord        dw    ?    ;object X location in pixels
  53. XInc        dw    ?    ;# of pixels to increment
  54.                 ; location by in the X
  55.                 ; direction on each move
  56. XLeftLimit    dw    ?    ;left limit of X motion
  57. XRightLimit    dw    ?    ;right limit of X motion
  58. YCoord        dw    ?    ;object Y location in pixels
  59. YInc        dw    ?    ;# of pixels to increment
  60.                 ; location by in the Y
  61.                 ; direction on each move
  62. YTopLimit    dw    ?    ;top limit of Y motion
  63. YBottomLimit    dw    ?    ;bottom limit of Y motion
  64. PlaneSelect    db    ?    ;mask to select plane to
  65.                 ; which object is drawn
  66.         db    ?    ;to make an even # of words
  67.                 ; long, for better 286
  68.                 ; performance (keeps the
  69.                 ; following structure
  70.                 ; word-aligned)
  71. ObjectStructure    ends
  72. ;
  73. Data    segment    word 'DATA'
  74. ;
  75. ; Palette settings to give plane 0 precedence, followed by
  76. ; planes 1, 2, and 3. Plane 3 has the lowest precedence (is
  77. ; obscured by any other plane), while plane 0 has the
  78. ; highest precedence (displays in front of any other plane).
  79. ;
  80. Colors    db    000h ;background color=black
  81.     db    03ch ;plane 0 only=red
  82.     db    03ah ;plane 1 only=green
  83.     db    03ch ;planes 0&1=red (plane 0 priority)
  84.     db    039h ;plane 2 only=blue
  85.     db    03ch ;planes 0&2=red (plane 0 priority)
  86.     db    03ah ;planes 1&2=green (plane 1 priority)
  87.     db    03ch ;planes 0&1&2=red (plane 0 priority)
  88.     db    03fh ;plane 3 only=white
  89.     db    03ch ;planes 0&3=red (plane 0 priority)
  90.     db    03ah ;planes 1&3=green (plane 1 priority)
  91.     db    03ch ;planes 0&1&3=red (plane 0 priority)
  92.     db    039h ;planes 2&3=blue (plane 2 priority)
  93.     db    03ch ;planes 0&2&3=red (plane 0 priority)
  94.     db    03ah ;planes 1&2&3=green (plane 1 priority)
  95.     db    03ch ;planes 0&1&2&3=red (plane 0 priority)
  96.     db    000h ;border color=black
  97. ;
  98. ; Image of a hollow square.
  99. ; There's an 8-pixel-wide blank border around all edges
  100. ; so that the image erases the old version of itself as
  101. ; it's moved and redrawn.
  102. ;
  103. Square    label    byte
  104.     dw    48,6    ;height in pixels, width in bytes
  105.     rept    8
  106.     db    0,0,0,0,0,0    ;top blank border
  107.     endm
  108.     .radix    2
  109.     db    0,11111111,11111111,11111111,11111111,0
  110.     db    0,11111111,11111111,11111111,11111111,0
  111.     db    0,11111111,11111111,11111111,11111111,0
  112.     db    0,11111111,11111111,11111111,11111111,0
  113.     db    0,11111111,11111111,11111111,11111111,0
  114.     db    0,11111111,11111111,11111111,11111111,0
  115.     db    0,11111111,11111111,11111111,11111111,0
  116.     db    0,11111111,11111111,11111111,11111111,0
  117.     db    0,11111111,00000000,00000000,11111111,0
  118.     db    0,11111111,00000000,00000000,11111111,0
  119.     db    0,11111111,00000000,00000000,11111111,0
  120.     db    0,11111111,00000000,00000000,11111111,0
  121.     db    0,11111111,00000000,00000000,11111111,0
  122.     db    0,11111111,00000000,00000000,11111111,0
  123.     db    0,11111111,00000000,00000000,11111111,0
  124.     db    0,11111111,00000000,00000000,11111111,0
  125.     db    0,11111111,00000000,00000000,11111111,0
  126.     db    0,11111111,00000000,00000000,11111111,0
  127.     db    0,11111111,00000000,00000000,11111111,0
  128.     db    0,11111111,00000000,00000000,11111111,0
  129.     db    0,11111111,00000000,00000000,11111111,0
  130.     db    0,11111111,00000000,00000000,11111111,0
  131.     db    0,11111111,00000000,00000000,11111111,0
  132.     db    0,11111111,00000000,00000000,11111111,0
  133.     db    0,11111111,11111111,11111111,11111111,0
  134.     db    0,11111111,11111111,11111111,11111111,0
  135.     db    0,11111111,11111111,11111111,11111111,0
  136.     db    0,11111111,11111111,11111111,11111111,0
  137.     db    0,11111111,11111111,11111111,11111111,0
  138.     db    0,11111111,11111111,11111111,11111111,0
  139.     db    0,11111111,11111111,11111111,11111111,0
  140.     db    0,11111111,11111111,11111111,11111111,0
  141.     .radix    10
  142.     rept    8
  143.     db    0,0,0,0,0,0    ;bottom blank border
  144.     endm
  145. ;
  146. ; Image of a hollow diamond with a smaller diamond in the
  147. ; middle.
  148. ; There's an 8-pixel-wide blank border around all edges
  149. ; so that the image erases the old version of itself as
  150. ; it's moved and redrawn.
  151. ;
  152. Diamond    label    byte
  153.     dw    48,6    ;height in pixels, width in bytes
  154.     rept    8
  155.     db    0,0,0,0,0,0    ;top blank border
  156.     endm
  157.     .radix    2
  158.     db    0,00000000,00000001,10000000,00000000,0
  159.     db    0,00000000,00000011,11000000,00000000,0
  160.     db    0,00000000,00000111,11100000,00000000,0
  161.     db    0,00000000,00001111,11110000,00000000,0
  162.     db    0,00000000,00011111,11111000,00000000,0
  163.     db    0,00000000,00111110,01111100,00000000,0
  164.     db    0,00000000,01111100,00111110,00000000,0
  165.     db    0,00000000,11111000,00011111,00000000,0
  166.     db    0,00000001,11110000,00001111,10000000,0
  167.     db    0,00000011,11100000,00000111,11000000,0
  168.     db    0,00000111,11000000,00000011,11100000,0
  169.     db    0,00001111,10000001,10000001,11110000,0
  170.     db    0,00011111,00000011,11000000,11111000,0
  171.     db    0,00111110,00000111,11100000,01111100,0
  172.     db    0,01111100,00001111,11110000,00111110,0
  173.     db    0,11111000,00011111,11111000,00011111,0
  174.     db    0,11111000,00011111,11111000,00011111,0
  175.     db    0,01111100,00001111,11110000,00111110,0
  176.     db    0,00111110,00000111,11100000,01111100,0
  177.     db    0,00011111,00000011,11000000,11111000,0
  178.     db    0,00001111,10000001,10000001,11110000,0
  179.     db    0,00000111,11000000,00000011,11100000,0
  180.     db    0,00000011,11100000,00000111,11000000,0
  181.     db    0,00000001,11110000,00001111,10000000,0
  182.     db    0,00000000,11111000,00011111,00000000,0
  183.     db    0,00000000,01111100,00111110,00000000,0
  184.     db    0,00000000,00111110,01111100,00000000,0
  185.     db    0,00000000,00011111,11111000,00000000,0
  186.     db    0,00000000,00001111,11110000,00000000,0
  187.     db    0,00000000,00000111,11100000,00000000,0
  188.     db    0,00000000,00000011,11000000,00000000,0
  189.     db    0,00000000,00000001,10000000,00000000,0
  190.     .radix    10
  191.     rept    8
  192.     db    0,0,0,0,0,0    ;bottom blank border
  193.     endm
  194. ;
  195. ; List of objects to animate.
  196. ;
  197.     even    ;word-align for better 286 performance
  198. ;
  199. ObjectList    label    ObjectStructure
  200.  ObjectStructure <1,21,Diamond,88,8,80,512,16,0,0,350,RED>
  201.  ObjectStructure <1,15,Square,296,8,112,480,144,0,0,350,RED>
  202.  ObjectStructure <1,23,Diamond,88,8,80,512,256,0,0,350,RED>
  203.  ObjectStructure <1,13,Square,120,0,0,640,144,4,0,280,BLUE>
  204.  ObjectStructure <1,11,Diamond,208,0,0,640,144,4,0,280,BLUE>
  205.  ObjectStructure <1,8,Square,296,0,0,640,144,4,0,288,BLUE>
  206.  ObjectStructure <1,9,Diamond,384,0,0,640,144,4,0,288,BLUE>
  207.  ObjectStructure <1,14,Square,472,0,0,640,144,4,0,280,BLUE>
  208.  ObjectStructure <1,8,Diamond,200,8,0,576,48,6,0,280,GREEN>
  209.  ObjectStructure <1,8,Square,248,8,0,576,96,6,0,280,GREEN>
  210.  ObjectStructure <1,8,Diamond,296,8,0,576,144,6,0,280,GREEN>
  211.  ObjectStructure <1,8,Square,344,8,0,576,192,6,0,280,GREEN>
  212.  ObjectStructure <1,8,Diamond,392,8,0,576,240,6,0,280,GREEN>
  213. ObjectListEnd    label    ObjectStructure
  214. ;
  215. Data    ends
  216. ;
  217. ; Macro to output a word value to a port.
  218. ;
  219. OUT_WORD    macro
  220. if WORD_OUTS_OK
  221.     out    dx,ax
  222. else
  223.     out    dx,al
  224.     inc    dx
  225.     xchg    ah,al
  226.     out    dx,al
  227.     dec    dx
  228.     xchg    ah,al
  229. endif
  230.     endm
  231. ;
  232. ; Macro to output a constant value to an indexed VGA
  233. ; register.
  234. ;
  235. CONSTANT_TO_INDEXED_REGISTER    macro ADDRESS, INDEX, VALUE
  236.     mov    dx,ADDRESS
  237.     mov    ax,(VALUE shl 8) + INDEX
  238.     OUT_WORD
  239.     endm
  240. ;
  241. Code    segment
  242.     assume    cs:Code, ds:Data
  243. Start    proc    near
  244.     cld
  245.     mov    ax,Data
  246.     mov    ds,ax
  247. ;
  248. ; Set 640x350 16-color mode.
  249. ;
  250.     mov    ax,0010h    ;AH=0 means select mode
  251.                 ;AL=10h means select
  252.                 ; mode 10h
  253.     int    10h        ;BIOS video interrupt
  254. ;
  255. ; Set the palette up to provide bit-plane precedence. If
  256. ; planes 0 & 1 overlap, the plane 0 color will be shown;
  257. ; if planes 1 & 2 overlap, the plane 1 color will be
  258. ; shown; and so on.
  259. ;
  260.     mov    ax,(10h shl 8) + 2    ;AH = 10h means
  261.                     ; set palette
  262.                     ; registers fn
  263.                     ;AL = 2 means set
  264.                     ; all palette
  265.                     ; registers
  266.     push    ds            ;ES:DX points to
  267.     pop    es            ; the palette
  268.     mov    dx,offset Colors    ; settings
  269.     int    10h            ;call the BIOS to
  270.                     ; set the palette
  271. ;
  272. ; Draw the static backdrop in plane 3. All the moving images
  273. ; will appear to be in front of this backdrop, since plane 3
  274. ; has the lowest precedence the way the palette is set up.
  275. ;
  276.     CONSTANT_TO_INDEXED_REGISTER SC_INDEX, MAP_MASK, 08h
  277.                 ;allow data to go to
  278.                 ; plane 3 only
  279. ;
  280. ; Point ES to display memory for the rest of the program.
  281. ;
  282.     mov    ax,VGA_SEGMENT
  283.     mov    es,ax
  284. ;
  285.     sub    di,di
  286.     mov    bp,SCREEN_HEIGHT/16    ;fill in the screen
  287.                     ; 16 lines at a time
  288. BackdropBlockLoop:
  289.     call    DrawGridCross        ;draw a cross piece
  290.     call    DrawGridVert        ;draw the rest of a
  291.                     ; 15-high block
  292.     dec    bp
  293.     jnz    BackdropBlockLoop
  294.     call    DrawGridCross        ;bottom line of grid
  295. ;
  296. ; Start animating!
  297. ;
  298. AnimationLoop:
  299.     mov    bx,offset ObjectList    ;point to the first
  300.                     ; object in the list
  301. ;
  302. ; For each object, see if it's time to move and draw that
  303. ; object.
  304. ;
  305. ObjectLoop:
  306. ;
  307. ; See if it's time to move this object.
  308. ;
  309.     dec    [bx+Delay]    ;count down delay
  310.     jnz    DoNextObject    ;still delaying-don't move
  311.     mov    ax,[bx+BaseDelay]
  312.     mov    [bx+Delay],ax    ;reset delay for next time
  313. ;
  314. ; Select the plane that this object will be drawn in.
  315. ;
  316.     mov    dx,SC_INDEX
  317.     mov    ah,[bx+PlaneSelect]
  318.     mov    al,MAP_MASK
  319.     OUT_WORD
  320. ;
  321. ; Advance the X coordinate, reversing direction if either
  322. ; of the X margins has been reached.
  323. ;
  324.     mov    cx,[bx+XCoord]        ;current X location
  325.     cmp    cx,[bx+XLeftLimit]    ;at left limit?
  326.     ja    CheckXRightLimit    ;no
  327.     neg    [bx+XInc]        ;yes-reverse
  328. CheckXRightLimit:
  329.     cmp    cx,[bx+XRightLimit]    ;at right limit?
  330.     jb    SetNewX            ;no
  331.     neg    [bx+XInc]        ;yes-reverse
  332. SetNewX:
  333.     add    cx,[bx+XInc]        ;move the X coord
  334.     mov    [bx+XCoord],cx        ; & save it
  335. ;
  336. ; Advance the Y coordinate, reversing direction if either
  337. ; of the Y margins has been reached.
  338. ;
  339.     mov    dx,[bx+YCoord]            ;current Y location
  340.     cmp    dx,[bx+YTopLimit]       ;at top limit?
  341.     ja    CheckYBottomLimit       ;no
  342.     neg    [bx+YInc]            ;yes-reverse
  343. CheckYBottomLimit:
  344.     cmp    dx,[bx+YBottomLimit]    ;at bottom limit?
  345.     jb    SetNewY                ;no
  346.     neg    [bx+YInc]            ;yes-reverse
  347. SetNewY:
  348.     add    dx,[bx+YInc]            ;move the Y coord
  349.     mov    [bx+YCoord],dx            ; & save it
  350. ;
  351. ; Draw at the new location. Because of the plane select
  352. ; above, only one plane will be affected.
  353. ;
  354.     mov    si,[bx+Image]        ;point to the
  355.                     ; object's image
  356.                     ; info
  357.     call    DrawObject
  358. ;
  359. ; Point to the next object in the list until we run out of
  360. ; objects.
  361. ;
  362. DoNextObject:
  363.     add    bx,size ObjectStructure
  364.     cmp    bx,offset ObjectListEnd
  365.     jb    ObjectLoop
  366. ;
  367. ; Delay as specified to slow things down.
  368. ;
  369. if SLOWDOWN
  370.     mov    cx,SLOWDOWN
  371. DelayLoop:
  372.     loop    DelayLoop
  373. endif
  374. ;
  375. ; If a key's been pressed, we're done, otherwise animate
  376. ; again.
  377. ;
  378. CheckKey:
  379.     mov    ah,1
  380.     int    16h        ;is a key waiting?
  381.     jz    AnimationLoop    ;no
  382.     sub    ah,ah
  383.     int    16h        ;yes-clear the key & done
  384. ;
  385. ; Back to text mode.
  386. ;
  387.     mov    ax,0003h    ;AL=03h means select
  388.                 ; mode 03h
  389.     int    10h
  390. ;
  391. ; Back to DOS.
  392. ;
  393.     mov    ah,4ch        ;DOS terminate function
  394.     int    21h        ;done
  395. ;
  396. Start    endp
  397. ;
  398. ; Draws a single grid cross-element at the display memory
  399. ; location pointed to by ES:DI. 1 horizontal line is drawn
  400. ; across the screen.
  401. ;
  402. ; Input: ES:DI points to the address at which to draw
  403. ;
  404. ; Output: ES:DI points to the address following the
  405. ;        line drawn
  406. ;
  407. ; Registers altered: AX, CX, DI
  408. ;
  409. DrawGridCross    proc    near
  410.     mov    ax,0ffffh    ;draw a solid line
  411.     mov    cx,SCREEN_WIDTH/2-1
  412.     rep    stosw        ;draw all but the rightmost
  413.                 ; edge
  414.     mov    ax,0080h
  415.     stosw            ;draw the right edge of the
  416.                 ; grid
  417.     ret
  418. DrawGridCross    endp
  419. ;
  420. ; Draws the non-cross part of the grid at the display memory
  421. ; location pointed to by ES:DI. 15 scan lines are filled.
  422. ;
  423. ; Input: ES:DI points to the address at which to draw
  424. ;
  425. ; Output: ES:DI points to the address following the
  426. ;        part of the grid drawn
  427. ;
  428. ; Registers altered: AX, CX, DX, DI
  429. ;
  430. DrawGridVert    proc    near
  431.     mov    ax,0080h    ;pattern for a vertical line
  432.     mov    dx,15        ;draw 15 scan lines (all of
  433.                 ; a grid block except the
  434.                 ; solid cross line)
  435. BackdropRowLoop:
  436.     mov    cx,SCREEN_WIDTH/2
  437.     rep    stosw        ;draw this scan line's bit
  438.                 ; of all the vertical lines
  439.                 ; on the screen
  440.     dec    dx
  441.     jnz    BackdropRowLoop
  442.     ret
  443. DrawGridVert    endp
  444. ;
  445. ; Draw the specified image at the specified location.
  446. ; Images are drawn on byte boundaries horizontally, pixel
  447. ; boundaries vertically.
  448. ; The Map Mask register must already have been set to enable
  449. ; access to the desired plane.
  450. ;
  451. ; Input:
  452. ;    CX - X coordinate of upper left corner
  453. ;    DX - Y coordinate of upper left corner
  454. ;    DS:SI - pointer to draw info for image
  455. ;    ES - display memory segment
  456. ;
  457. ; Output: none
  458. ;
  459. ; Registers altered: AX, CX, DX, SI, DI, BP
  460. ;
  461. DrawObject    proc    near
  462.     mov    ax,SCREEN_WIDTH
  463.     mul    dx    ;calculate the start offset in
  464.             ; display memory of the row the
  465.             ; image will be drawn at
  466.     shr    cx,1
  467.     shr    cx,1
  468.     shr    cx,1    ;divide the X coordinate in pixels
  469.             ; by 8 to get the X coordinate in
  470.             ; bytes
  471.     add    ax,cx    ;destination offset in display
  472.             ; memory for the image
  473.     mov    di,ax    ;point ES:DI to the address to
  474.             ; which the image will be copied
  475.             ; in display memory
  476.     lodsw
  477.     mov    dx,ax    ;# of lines in the image
  478.     lodsw        ;# of bytes across the image
  479.     mov    bp,SCREEN_WIDTH
  480.     sub    bp,ax    ;# of bytes to add to the display
  481.             ; memory offset after copying a line
  482.             ; of the image to display memory in
  483.             ; order to point to the address
  484.             ; where the next line of the image
  485.             ; will go in display memory
  486. DrawLoop:
  487.     mov    cx,ax    ;width of the image
  488.     rep    movsb    ;copy the next line of the image
  489.             ; into display memory
  490.     add    di,bp    ;point to the address at which the
  491.             ; next line will go in display
  492.             ; memory
  493.     dec    dx    ;count down the lines of the image
  494.     jnz    DrawLoop
  495.     ret
  496. DrawObject    endp
  497. ;
  498. Code    ends
  499.     end    Start
  500.  
  501.