Drawing Sprites

To get a sprite on the screen we need to choose one of the hardware sprites and set its attributes. Things like its x,y position, which sprite pattern to use and so on.

The attributes are what tell the Next how to display our chosen sprites.

These don’t have an official name, the Wiki just calls them “sprites” so I’m going to call them sprite attribute slots. They represent the actual 128 hardware sprites we can use.

Think of these as the instances of the sprites in your game that the Next will draw and manage for us using its hardware sprite system.

Don’t mix them up with the sprite patterns from earlier.

Setting up the Next registers

Which attribute slot we use is up to us and is part of our game’s logic, not the Next’s sprite system.

We’ll use slot zero as it makes the most sense.

Organising what each of the 128 hardware sprites is being used for is our job. In these examples we’re going to do this manually.

We do this with Next register hex 303B which in Z88DK has a macro called IO_SPRITE_SLOT

This has two functions. The first is to choose which of the 128 hardware sprites we are going to be setting attributes for

I have a function to do this:

#define SPRITE_ATTRIB_MASK      0x7F
void set_sprite_attrib_slot(uint8_t sprite_slot)

All it does is builds up the correct bit pattern to be sent to the Next’s sprite slot Nextreg. The logical AND just makes sure we only ever set the bottom 7 bits. The MSB will always be zero, as the Next only has 128 sprites.

Next register 303B is also used to tell the Next which of the 64 sprite patterns to use and whether that pattern is a 4 bit or 8 bit image. You can read about the bit pattern it contains on this page

Sprite Attributes

So now we’ve selected the attribute slot, the Next needs telling what to do with it by setting sprite attributes.

There are up to five attribute assignments that need doing.

These are written to sprite attribute upload port 57 hex

You must upload at least four attributes, the fifth is optional.

Attributes are how you program the sprite system.

The five attributes are

  • Attribute zero - sprite’s X position least significant 8 bits

  • Attribute one - sprite’s Y position least significant 8 bits

  • Attribute two - This is a real mixture of many things. If you’re a bit rusty twiddling bits in a byte, programming sprites will soon sharpen those skills!
    • Pallete offsett (ignore this for this explanation)

    • mirroring, rotating

    • the 9th bit for the X co-ord

    • and a flag to say if this sprite’s palette offset is relative to something beyond the scope of this video

  • Attribute three - More bits mashed together
    • Flag to mark the sprite visible

    • A flag to enable attribute byte 4

    • six bits for the sprite pattern ID to use

  • Attribute four - This is optional and depends on whether you switched it on in attribute three, and it’s very confusing without a bit of a run-up. We’ll get to this in due course.

After that the sprite appears, and will stay on the screen all by itself.

Sample Code

void set_sprite_attributes(uint8_t sprite_pattern_slot,
                        uint16_t x,
                        uint8_t y,
                        uint8_t palette_offset,
                        uint8_t sprite_flags,
                        bool visible)
    uint8_t pattern_slot = sprite_pattern_slot & SPRITE_PATTERN_MASK;

    if (visible)
        pattern_slot = pattern_slot | SPRITE_VISIBLE_MASK;

    IO_SPRITE_ATTRIBUTE = (palette_offset << PALETTE_OFFSET_SHIFT) | X_MSB(x) | sprite_flags;
    IO_SPRITE_ATTRIBUTE = pattern_slot;

Summary of how to set up sprites

  • Set Next Register hex 303B to zero to reset the sprite system

  • Upload sprite pattern data to port 5B hex

  • Set next register 303B to zero again to select sprite zero

  • Write a minimum of four bytes to port 57
    • X and Y position of the sprite

    • Flags for mirror and rotation

    • A visible flag

    • The sprite pattern ID to use