Skip to main content

Palix: sprites

The video system can display up to 64 sprites at one time. Also called a "movable object block," a sprite is a rectangular bitmap that may include transparent pixels. The sprite width and height can be any combination of 8, 16, 32, or 48 pixel dimensions. For example, an 8 × 8 sprite might be used to display a mouse pointer, whereas a 16 × 48 sprite might show a tall person walking.

Note: The Hybrix designer lets you design resources that are also called "sprites" with features such as animation clips and board placement. That concept is a bit different from io_sprite, which is the primitive hardware interface. For example, the Hybrix framework's actor class animates sprite clips by periodically updating io_sprite.pixels_address to point to the next animation frame.

Basics

The io_sprite.x and io_sprite.y fields position the sprite on the screen. The coordinate origin is in the upper-left corner of the screen, with the Y axis pointing downwards and the X axis pointing to the right.

The io_sprite.pixels_address field stores the memory address of the pixels, one byte per pixel. The number of pixels is io_sprite.widthio_sprite.height, and the first byte is the upper-left pixel of the sprite. The bytes are interpreted according to the color palette of the io_sprite.theme. A zero byte is typically transparent.

Note: If io_sprite.pixels_address points to a Hybrix language array, it should be the address of the first array element, not the address of the memory block (which for a dynamic array starts with an array size trio).

Display priority

There are four sprite layers. Layer #0 appears in front of Tilemap A. Layer #1 appears between Tilemap A and Tilemap B, Layer #2 between Tilemap B and Tilemap C, and Layer #3 appears behind all the tilemaps. The layer assignment is controlled by io_sprite.flags, or actor.layer when using the framework engine.

LevelNotes
Sprite Layer #0🡅 (displayed in the front)
Tile Layer Ashows the framework console
Sprite Layer #1actor.layer default for the framework actors
Tile Layer Bused for the framework scene tilemap
Sprite Layer #2
Tile Layer C
Sprite Layer #3🡇 (displayed in the back)

If no sprite or tilemap assigns a color to a given pixel, then io::background_color determines the color.

Within a layer, the io::sprites array is rendered from front to back. For example, io::sprites[0] will appear in front of io::sprites[1] if both sprites belong to the same layer.

io_sprite.flags can "flip" sprites horizontally (X) or vertically (Y) or both. This is a bitmap reflection transform that does not alter the sprite's visual position. For example, flipping horizontally can be used to make a game character face to the left instead of to the right. Flipping vertically would make them appear upside down.

For square sprites (whose width and height are equal), io_sprite.flags can also rotate the sprite 90° clockwise. The 180° and 270° rotations can be obtained by combining rotation and flipping.

Code sample

This code sample animates an 8 × 8 sprite by directly writing to I/O memory.

module main
func start()
var sprite: io_sprite
var pixels: byte[size 64]
var i: int

pixels <- new byte[size 64]()
i <- 0
loop
if i = 64
do drop
pixels[i] <- to_byte(i % 7)
i <- i + 1
end loop

sprite <- io::sprites[0]
sprite.width <- 8
sprite.height <- 8
# (Since this is a static array, we don't need to add 3)
sprite.pixels_address <- to_address(pixels)

loop
sprite.x <- to_pair(io::frame_counter % 320)
sprite.y <- 1
end loop
end func
end module

I/O definitions

class io_sprite # size 16
# Screen coordinates of upper-left corner of sprite
var x: pair, y: pair

# Possible values: 8, 16, 32, 48
var width: byte, height: byte

# Layer:
# 0 = in front of all tilemaps
# 1 = behind tilemap A, in front of B
# 2 = behind tilemap B, in front of C
# 3 = behind all tilemaps
#
# Transform:
# +4 = flip X (horizontal)
# +8 = flip Y (vertical)
# +16 = rotate clockwise 90 degrees, only if sprite is square
var flags: byte

# The theme is an index (0..31) into io::themes
var theme: byte

# The address of the pixel buffer. To hide the sprite, set pixels_address=0
var pixels_address: int

var reserved: int
end class
module io
. . .
# Palix video system
var background_color: byte located at $d0_0300
. . .
inset sprites: io_sprite[inset 64] located at $d0_0400 # ..$d0_07ff
. . .
end module