Sprite

From C64-Wiki

Jump to: navigation, search

A sprite, also referred to as a Movable Object Block (abbreviated to MOB) in Commodore literature, is a piece of graphics that can move and be assigned attributes independent of other graphics or text on the screen. The VIC-II, which is responsible for this feature of the C-64, supports up to eight sprites, but through the use of raster interrupt programming more than eight sprites may be displayed simultaneously.

While managing sprites is notorious for the flurry of POKEs necessary to set them up, their big strength lie in the ability to quickly and easily move a graphical object and change its shape, merely by specifying coordinates and setting a pointer – eliminating the need to constantly draw and erase graphical objects pixel-by-pixel.

Sprite developing help

Contents

[edit] Sprite graphics

The "pattern" or "design" of both multicolor and high-res sprites always fits in to a "grid" of 24 bits in width, and 21 bits in height; a total of 504 bits, which in turn fit into 63 bytes. These 63 bytes are stored in RAM within the current VIC-bank, beginning at an address divisible by 64; i.e. 0, 64, 128, 192, 256 etc.

This arrangement "interleaves" one unused byte in each avaliable 64-byte "block"; the contents of this "64th byte" has no influence on the sprite's appearance. In theory, one VIC-bank with no ROM charset mirror can hold 256 sprite patterns, but allowing for a text screen and a character set, the practical number is no larger than 208 different patterns.

[edit] High resolution sprite pattern

Data for a high resolution sprite

To the right is a 24×21 raster image depicting a solid circle: The grid is divided into "strips" of 8 pixels, or bits, i.e. into individual bytes. Each byte is read with the leftmost bit as the most significant, and the rightmost bit as the least significant one. The bytes are read from left to right, row by row (just like reading ordinary text), and converting the bit pattern for this example into decimal byte values yield the figures indicated to the right of the grid. The 63-byte sequence forming this sprite thus begins with 0, 126, 0, 3, 255, 192, 7, ...

Since a bit can assume one of two states, each pixel in a high resolutuion sprite can do one of two things:

  • For bits set to "0" in the sprite data set, the corresponding pixel will be transparent, i.e. whatever graphics or color is behind the sprite, will show through these pixels.
  • Bits set to "1" will cause the corresponding pixels in the sprite to assume the individual color set for each sprite (see the section color settings below). Such pixels can appear either in front of or "hide" behind other sprites or other graphics; see the section on sprite priority below.

[edit] Multicolor sprite pattern

In multicolor sprites the bits a grouped in pairs, forming pixels that are twice the width of high resolution pixels. Since each such multicolor pixel is defined by two bits of data rather than one, each pixel can do one of four things:

  • Pixels with a bit pair of "00" (white in the illustration) appear transparent, like "0" bits do in high resolution mode.
  • Pixels with a bit pair of "01" (cyan in the illustration) will have the color specified in address 53285/$D025.
  • Pixels with a bit pair of "11" (dark blue in the illustration) will have the color specified in address 53286/$D026.
  • Pixels with a bit pair of "10" (light blue in the illustration) will have the color specified assigned to the sprite in question in the range 53287–53294/$D027–D02E.

Note that two of the three "visible" (non-transparent) colors will be common for all eight sprites, whereas the third visible color may be set individually for each sprite.

[edit] Settings

Besides setting up data for the pattern in RAM, using sprites involves some further initialization work. In the following discussion of the sprite-related VIC-II registers, the eight sprites are consequently referred to as sprite #0 thru sprite #7.

[edit] Sprite Enable

Each bit in address 53269/$D015 acts like a "switch" that turns one of the eight sprites "on" or "off"; set the bit to "1" to enable the corresponding sprite. or "0" to hide it. The least significant bit refers to sprite #0, and the most sigificant bit to sprite #7.

[edit] Sprite pointers

The location of the sprite pointers follow that of the text screen, so that if the VIC-II has been "told" (through address 53272) that the text screen RAM begins at address S, the sprite pointers reside at addresses S+1016 thru S+1023. Since the default text screen RAM address is 1024, this puts the sprite pointers at addresses 2040 (for sprite #0) thru 2047 (for sprite #7), or $07F8–07FF in hexadecimal.

To make a given sprite show the pattern that's stored in RAM at an address A (which must be divisible with 64), set the contents of the corresponding sprite pointer address to A divided by 64. For instance, if the sprite pattern begins at address 704, the pointer value will be 704 / 64 = 11.

[edit] Sprite locations

Spritex coordinatey coordinate
#053248/$D00053249/$D001
#153250/$D00253251/$D003
#253252/$D00453253/$D005
#353254/$D00653255/$D007
#453256/$D00853257/$D009
#553258/$D00A53259/$D00B
#653260/$D00C53261/$D00D
#753262/$D00E53263/$D00F

Each sprite has it's own set of coordinate registers, which determine where on the screen the sprite appears, as indicated in the table to the right. However, the sprites can move across more than 256 pixels in the horizontal direction, and so their x coordinates require nine bits; one more than the eight available in each of the addresses shown.

Because of this, the x coordinate addresses given in the table only holds the eight least significant bits of the x coordinates for the respective sprites. The ninth and most significant bit for each of the eight sprites are "gathered" in address 53264/$D010; the least significant bit here corresponds to sprite #0, and the most sigificant bit to sprite #7.

[edit] High resolution or multicolor mode

In address 53276, each bit is set to "tell" VIC-II which sprites are to be in high resolution mode (bit set to "0"), and which to display in multicolor mode (bit set to "1"). The least significant bit controls sprite #0, and the most sigificant bit sprite #7.

[edit] Double height and/or width

By default, i.e. without the use of this feature, a sprite will cover an area 24 (high resolution) pixels wide and 21 pixels high, but by setting bits in registers 53277/$D01D and 53271/$D017, each sprite may be individually "stretched" to twice the width and/or twice the height. In both registers, the least significant bit affects sprite #0, and the most sigificant bit sprite #7.

Notice that regardles of whether the sprite has been "doubled" in either or both directions, the graphic pattern displayed by the sprite still comes from the same 63 bytes: The expanded size comes at the cost of more coarse, "blocky" graphics.

[edit] Color settings

SpriteColor reg.
#053287/$D027
#153288/$D028
#253289/$D029
#353290/$D02A
#453291/$D02B
#553292/$D02C
#653293/$D02D
#753294/$D02E

Both multicolor and high resolution sprites have one "transparent" color, and one "solid" color that can be individually set for each sprite, using the addresses specified in the table at right.

Besides these two, multicolor mode offers two more colors which are common for all eight sprites:

  • 53285/$D025 is the common color displayed for "01" bit pairs in the sprite data, and
  • 53286/$D026 is the common color displayed for "11" bit pairs in the sprite data.

[edit] Sprite priority

In the context of sprites, "background" refers to the text screen or other "non-sprite" graphics shown on the screen along with the sprites: Through manipulating the bits in address 53275/$D01B, sprites can be set to appear "behind" (bits set to "1") or "in front of" (bits set to "0") such background graphics. The least significant bit affects sprite #0, and the most sigificant bit sprite #7.

Note that the priority amongst the sprites themselves are "hardwired": A sprite with a lower number will always overlap, or appear "in front of" a sprite with a higher number; e.g. sprite #3 will appear in front of #5, should they happen to overlap.

[edit] Collision detection

The VIC-II provides hardware-supported collision detection between sprites and other graphics: "Collision" in this context means that one or more visible pixels in one visible sprite actually overlap one or more visible pixels in either another sprite, or in the background graphics.

[edit] Polling for collisions

There are two VIC registers that can be polled to see if a collision involving sprites have occured:

  • Sprites involved in a collision with other sprites will have their respective bits set to "1" in address 53278/$D01E – all other sprites will have a "0" bit here.
  • Sprites involved in a collision with background graphics will have their respective bits set to "1" in address 53279/$D01F – all other sprites will report a "0".

As with all other "one bit per sprite" registers, the least significant bit affects sprite #0, and the most sigificant bit sprite #7.

[edit] Interrupt on collision

Both the interrupt event register (at address 53273/$D019) and interrupt enable register (at address 53274/$D01A) have provisions for raising IRQ-type interrupts at the CPU whenever collisions occur:

  • Bit 2 (weight 4) in both registers concern sprite-to-sprite collisions, and
  • Bit 1 (weight 2) in both registers concern sprite-to-background collisions.
Personal tools
Help and Feedback
In other languages