CHAPTER 16
     
     
                       PLAYER AND MISSILE (PM) GRAPHICS
     
     
     Players and missiles (called sprites on some computers) are movable
     objects which are independent of the normal graphics.
     
     Player and missile graphics are fairly straight forward.  Once the
     computer is set-up for PM graphics, five 8-pixel-wide columns can be
     displayed on the screen.  The horizontal resolution (width of each
     pixel) and the vertical resolution (number of scan lines per pixel)
     are variable.  The horizontal position of each column is determined by
     it's horizontal position register.  Each column is simply a
     representation of a bit map in a certain block of memory.  If you want
     to draw an object on the screen, you simply put a bit map representing
     it in the proper memory block.  The vertical position of an object is
     determined by the location of it's bit map in memory.  For example, if
     you want to draw a happy face in the middle of the screen, you put a
     happy face bit map in the middle of one of the memory blocks
     controlling one of the columns.
     
                  One column (player) displayed on the screen
     
     
              ---------- first byte of a block
              |        |
              |        |
          ------------------------------
          |   |        |               |
          |   |        |               |
          |   |        |               |
          |   |        |               |
          |   |        |               |
          |   |        |               |
          |   |  ++++  |      visible  |
          |   | +    + |               |
          |   |+ +  + +|               |
          |   |+      +|       area    |
          |   |++    ++|               |
          |   |+ ++++ +|--object       |
          |   | +    + |  bit map      |
          |   |  ++++  |               |
          |   |        |               |
          |   |        |               |
          |   |        |               |
          ------------------------------
              |        |
              |        |
              ---------- last byte of a block
    


             Horizontal positions
     
     $00 $30                          $CE    $FF
     (0)  (48)                        (206) (255)
      |   |                            |      |
      |   Left edge           right edge      |
      |                                       |
      Far left                        far right
     
     
     To move the happy face vertically you would move the entire bit map in
     memory.  To move the happy face horizontally you change the number in
     the horizontal position register for the proper player.
     
     One of the players can be (and often is) split into four columns of
     two pixels wide each.  These columns are then called missiles.  In
     this case, each missile has it's own horizontal position register.
     
     SETTING UP PM GRAPHICS
     
     PM graphics are enabled by the direct memory access control register,
     DMACTL [$D400 (54272)].  The program using PM graphics will usually
     use the shadow register, SDMCTL [$022F (559)].
     
                                DMACTL (SDMCTL)
     
          7 6 5 4 3 2 1 0
         -----------------
         |0|0|  control  |
         -----------------
     
      bits
     
          5    1 = enable display list reading
          4    0 = one line player resolution
               1 = two line player resolution
          3    1 = enable four players
          2    1 = enable fifth player or missiles
      1 & 0   00 = no background
              01 = narrow background (128 color clocks,
                   1 color clock equals 2 GRAPHICS 8 pixels)
              10 = normal background (160 color clocks)
              11 = wide background (192 color clocks)
     
     Normally, bits 5 and 1 are set to 1.  Bits 4, 3 and 2 are used to
     enable players and/or missiles accordingly.
     
     Once DMACTL is set up for the type of PM graphics to enable, the
     graphics control register, GRACTL [$D01D (53277)], is used to actually
     enable the PM graphics.
     
                                    GRACTL
     
          7 6 5 4 3 2 1 0
         -----------------
         |not used | | | |
         -----------------
     
     
      Bits
     
          2    1 = latch paddle triggers
          1    1 = enable four players
          0    1 = enable fifth player or missiles
     
     If only DMACTL is set up, the ANTIC chip will access memory for PM
     graphics but will not display them.
     
     Next, the memory area used for the PM bit maps must be set.  This
     block must start on a 2K (8 page) boundary if single line resolution
     is used and a 1K (4 page) boundary for two line resolution.
     
     The page number where the bit map starts is stored in the PM base
     register, PMBASE [$D407 (54279)].  For one line resolution this number
     will be a multiple of 8.  For two line resolution it will be a
     multiple of 4.  PMBASE holds the MSB of the address of the PM bit map.
     The LSB will always be 0 so it need not be specified.
     
                                The PM bit maps
     
          2 line resolution
          128 bytes (1/2 page)
          per player
     
          -----------------   start + 0
          |               |\
          +---------------+ 1-1/2 page
          |               | (384 bytes)
          +===============+ unused
          |               |/
          +---------------+  +$180 (384)
          |M3 |M2 |M1 |M0 | fifth player or missiles
          +===============+  +$200 (512)
          | player 0 map  |
          +---------------+  +$280 (640)
          | player 1 map  |
          +===============+  +$300 (768)
          | player 2 map  |
          +---------------+  +$380 (896)
          | player 3 map  |
          +===============+  +$400 (1024)
     
          1 line resolution
          256 bytes (1 page)
          per player


          -----------------   start + 0
          |               |\
          +               +
          |               |
          +===============+
          |               |  768 bytes
          +               +
          |               |  (3 pages)
          +===============|
          |               |  unused
          +               +
          |               |/
          +===============+  +$300 (768)
          |   |   |   |   | fifth player
          +M3 |M2 |M1 |M0 | or missiles
          |   |   |   |   |
          +===============+  +$400 (1024)
          |               |
          + player 0 map  +
          |               |
          +===============+  +$500 (1280)
          |               |
          + player 1 map  +
          |               |
          +===============+  +$600 (1536)
          |               |
          + player 2 map  +
          |               |
          +===============+  +$700 (1792)
          |               |
          + player 3 map  +
          |               |
          +===============+  +$800 (2048)
                                                                           




                    Example of using P/M graphics in BASIC
     
     0 REM ---LABEL REGISTERS ETC
     10 LINES=2
     20 VERT=120
     22 IF LINES=2 THEN VERT=VERT/2
     30 PM0=1024
     32 IF LINES=2 THEN PM0=PM0/2
     40 HORIZ=120
     50 PCOLR0=704
     60 SDMCTL=559
     70 SIZEP0=53256
     80 HPOSP0=53248
     90 SDMCTL=559
     100 PMRAM=PEEK(106)-16
     110 PMBASE=54279
     120 GRACTL=53277
     130 PMSTART=PMRAM*256+PM0
     200 REM ---SET REGISTERS
     210 POKE SDMCTL,62
     212 IF LINES=2 THEN POKE SDMCTL,46
     220 POKE SIZEP0,1
     230 POKE HPOSP0,HORIZ
     240 POKE PCOLR0,88
     250 POKE PMBASE,PMRAM
     260 POKE GRACTL,3
     300 REM ---DRAW PLAYER
     310 POKE PMSTART+VERT,60
     320 POKE PMSTART+VERT+1,66
     330 POKE PMSTART+VERT+2,165
     340 POKE PMSTART+VERT+3,129
     350 POKE PMSTART+VERT+4,195
     360 POKE PMSTART+VERT+5,189
     370 POKE PMSTART+VERT+6,66
     380 POKE PMSTART+VERT+7,60
     
     The above program will draw a happy face in about the middle of the
     screen using player 0.  To move the player horizontally, poke a
     different number into HPOSP0.  To draw the player in a different
     vertical position, change VERT.  To use a different player or missile,
     use the memory maps above to find the starting address of the player
     you want to use.  For example, to use player 1 change line 40 to
     PM1=1280.  Then change line 130 to PMSTART=PMRAM*256+PM1.  The
     variable "LINES" determines the vertical resolution.  The number poked
     into SIZEP0 determines the width.
     
     P/M PRIORITY
     
     The priorities of players, missiles and non-P/M graphics can be
     controlled by the PRIOR register [$D10B (53275)] and its shadow
     register, GPRIOR [$26F (623)].  Objects with higher priority will
     appear to move in front of lower priority objects.  The format of
     PRIOR is as follows:

    
                             PRIOR bit assignment
     
           7 6 5 4 3 2 1 0
          -----------------
          | | | | | | | | |
          -----------------
           1 6 3 1 8 4 2 1
           2 4 2 6
           8
     
     Bits
     
        7-6  Control the GTIA graphics modes.
     
              00 = normal
              01 = mode 9
              10 = mode 10
              11 = mode 11
     
          5    1 = multiple color player enable.  Permits
                   overlapping of players 0 and 1 or
                   2 and 3 with a third color in the
                   overlapped region.
     
          4    1 = fifth player enable.  All missiles
                   will assume the color controlled by
                   COLOR3 [$2C7 (711)].  missiles are
                   positioned together to make the fifth
                   player.
     
        3-0    Controls the priorities of players, missiles
     and other graphics.  Objects with higher priority will appear to move
     in front of those with lower priority.
     
     The following chart may need some clarification.  In the chart:
     
     PM0 = player 0 and missile 0
     
      C0 = COLOR0, plotted graphics controlled
           by color register 0 in the SETCOLOR
           command.
     
      P5 = all four missiles when combined
           into one player.
     
     BAK = the background, known as COLOR4 or color
           register 4 in the SETCOLOR command.
     
                                     Etc.
     
                     Bits 0-3 of PRIOR and P/M priorities
     

     Bit  3=1    2=1    1=1    0=1
     
           C0     C0    PM0    PM0   highest
           C1     C1    PM1    PM1   priority
          PM0     C2     C0    PM2
          PM1   C3+P5    C1    PM3
          PM2    PM0     C2     C0
          PM3    PM1   C3+P5    C1
           C2    PM2    PM2     C2
         C3+P5   PM3    PM3   C3+P5  lowest
          BAK    BAK    BAK    BAK   priority
     
     Only one priority bit can be set at a time.  If more than one priority
     bit is 1, overlapping areas of conflicting priorities will turn
     black.
     
     COLLISIONS
     
     Each player or missile has a register showing overlap (collisions)
     with other objects.  Each player has two registers assigned to it; one
     to detect collisions with other players and one to detect collisions
     with plotted objects.  Likewise each missile has two registers; one to
     detect collisions with players and one to detect collisions with
     plotted objects.  Careful use of these 16 registers can detect any
     type of collision.
     
     Each register uses only the lower 4 bits.  The bits which equal 1 tell
     what the associated object has collided with.  For example, to detect
     collisions of player 1 to other players examine P1PL [$D00D (53261)].
     
                      P1PL, player 1 to player collisions
     
           7 6 5 4 3 2 1 0
          -----------------
     P1PL |unused | | | | |
          -----------------
                   8 4 2 1
     
          3 = 1  collision with player 3
          2 = 1  collision with player 2
          1 = 1  invalid
          0 = 1  collision with player 0
     
                                     Etc.
     
     When looking for collisions with plotted objects, the bit number tells
     what color register is assigned to the object the collision was with. 
     For example, to detect collisions between player 1 and plotted objects
     (officially called the play field), P1PF [$D005 (53253)] is used.
     
                  P1PF, player 1 to ploted object collisions
     
           7 6 5 4 3 2 1 0
          -----------------
     P1PF |unused | | | | |
          -----------------
                   8 4 2 1
     
          3 = 1  collision with COLOR3
          2 = 1        "        COLOR2
          1 = 1        "        COLOR1
          0 = 1        "        COLOR0
     
                                     Etc.
     
     Once a collision occurs it remains indicated in its collision
     register.  To clear out all collision registers, write anything to
     HITCLR [$D01E (53278)].  STA HITCLR or POKE 53278,0 will do.
     
                   Useful database variables and OS equates
     
     
     HPOSP0 $D000     (53248): write: horizontal position of player 0
     M0PF     "          "   : read: missile 0 to plotted graphics collisions
     HPOSP1 $D001     (53249): write: horizontal position of player 1
     M1PF     "          "   : read: missile 1 to plotted graphics collisions
     HPOSP2 $D002     (53250): write: horizontal position of player 2
     M2PF     "          "   : read: missile 2 to plotted graphics collisions
     HPOSP3 $D003     (53251): write: horizontal position of player 3
     M3PF     "          "   : read: missile 3 to plotted graphics collisions
     HPOSM0 $D004     (53252): write: horizontal position of missile 0
     P0PF     "          "   : read: Player 0 to plotted graphics collisions
     HPOSM1 $D005     (53253): write: horizontal position of missile 1
     P1PF     "          "   : read: Player 1 to plotted graphics collisions
     HPOSM2 $D006     (53254): write: horizontal position of missile 2
     P2PF     "          "   : read: Player 2 to plotted graphics collisions
     HPOSM3 $D007     (53255): write: horizontal position of missile 3
     P3PF     "          "   : read: Player 3 to plotted graphics collisions
     SIZEP0 $D008     (53256): write: size of player 0
     M0PL     "          "   : read: missile 0 to player collisions
     SIZEP1 $D009     (53257): write: size of player 1
     M1PL     "          "   : read: missile 1 to player collisions
     SIZEP2 $D00A     (53258): write: size of player 2
     M2PL     "          "   : read: missile 2 to player collisions
     SIZEP3 $D00B     (53259): write: size of player 3
     M3PL     "          "   : read: missile 3 to player collisions
     SIZEM  $D00C     (53260): write: widths for all missiles
     P0PL     "          "   : read: player 0 to other player collisions
     GRAFP0 $D00D     (53261): write: player 0 graphics (used by OS)
     P1PL     "          "   : read: player 1 to other player collisions
     GRAPF1 $D00E     (53262): write: player 1 graphics
     P2PL     "          "   : read: player 2 to other player collisions
     GRAFP2 $D00F     (53263): write: player 2 graphics
     P3PL     "          "   : read: player 3 to other player collisions
     GRAPF3 $D010     (53264): write: player 3 graphics
     GRAFM  $D011     (53265): write: missile graphics (used by OS)
     COLPM0 $D012     (53266): color for player/missile 0
     COLPM1 $D013     (53267): color for player/missile 1
     COLPM2 $D014     (53268): color for player/missile 2
     COLPM3 $D015     (53269): color for player/missile 3
     COLPF0 $D016     (53270): color register 0
     COLPF1 $D017     (53271): color register 1
     COLPF2 $D018     (53272): color register 2
     COLPF3 $D019     (53273): color register 3
     COLBK  $D01A     (53274): background color (register 4)
     PRIOR  $D01B     (53275): priority select, GTIA modes
     GRACTL $D01D     (53277): graphics control
     HITCLR $D01E     (53278): writing anything clears all collision bits
     DMACTL $D400     (54272): direct memory access (DMA) control
     PMBASE $D407     (54279): start of P/M memory
     
                               Shadow registers
     
     SDMCTL $022F       (559): DMACTL
     GPRIOR $026F       (623): PRIOR
     PCOLR0 $02C0       (704): COLPM0
     PCOLR1 $02C1       (705): COLPM1
     PCOLR2 $02C2       (706): COLPM2
     PCOLR3 $02C3       (707): COLPM3
     COLOR0 $02C4       (708): COLPF0
     COLOR1 $02C5       (709): COLPF1
     COLOR2 $02C6       (710): COLPF2
     COLOR3 $02C7       (711): COLPF3
     COLOR4 $02C8       (712): COLBK

------------------------------------------------------------
[BACK] [CONTENTS] [NEXT]