Palix: tiles
A tilemap is rectangular grid of tiles, where each tile is a square made of pixels. The square is either 16 × 16 ("jumbo" tiles typically used for game levels) or 8 × 8 (typically used by fonts). The tile pictures come from a tileset, which is a collection of numbered tile images. For example, a video game forest might use a tile 7 for each bush, a tile 13 for a vertical segment of a dirt road, etc. As another example, the Hybrix text console is a tilemap where each tile is a text character (letter or number or punctuation mark or graphical glyph). In this case, the tileset represents a typeface font.
Note: The Hybrix framework defines two "tilemap" classes
TILEMAPandIO_TILEMAP. TheTILEMAPclass is used for designer art resources, whereasIO_TILEMAPdescribes the hardware interface for rendering. TheTILE_LAYERclass preparesIO_TILEMAPusing data fromTILEMAPandTILESET.
Screen dimensions
Here's a handy reference for measuring screen dimensions as tiles:
| Screen size | Units |
|---|---|
| 320 × 224 | pixels |
| 40 × 28 | regular tiles (8 × 8) |
| 20 × 14 | jumbo tiles (16 × 16) |
Rendering
A tilemap is a two dimensional grid of cells, arranged in left-to-right rows, starting from the top row. The rows increase downwards like the Y axis, and columns increase rightwards like the X axis. Each cell contains a 16-bit PAIR called a tile code, whose binary bits encode three pieces of information for that cell:
| Tile code bits | Values | Encoded field |
|---|---|---|
| 0…9 | 0 – 1023 | tile index: indicates which tile to show from the tileset |
| 10…14 | 0 – 31 | theme index: the color palette theme used in this cell |
| 15 | 0 or 1 | matte coloring: if 1, then the IO::MATTE_COLOR is applied in this cell |
If enabled, matte coloring replaces any transparent pixels with the globally specified IO::MATTE_COLOR. The HASCII {MAT} mode makes use of this feature to add a solid background for text fonts.
The IO_TILEMAP.X and IO_TILEMAP.Y fields position the entire tilemap 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 tileset data is an array of up to 1,024 tile images. IO::TILESET_A_ADDRESSES defines the tileset for IO::TILESET_A and so forth. The actual array size is indicated by IO_TILEMAP.TILE_COUNT, which is important to prevent oversized index values from causing memory faults.
Each array element of IO::TILESET_A_ADDRESSES stores the memory address of that tile's bitmap pixels, one byte per pixel, in left-to-right rows, starting from the top row. For regular 8 × 8 tiles, there will be 256 pixels. For "jumbo" 16 × 16 tiles, there will be 1,024 pixels. The first byte is the upper-left pixel of that tile.
Tilemap A always appears in front of Tilemap B, which always appears in front of Tilemap C. See display priority for sprite interaction with the tilemap.
Palix-sized tilemaps
The IO_TILEMAP::COL_COUNT and IO_TILEMAP::ROW_COUNT locations must have one of these dimensions:
16, 32, 64, 128, or 256
If any other number is used, it is considered an error—Palix will not display that tilemap at all.
The Hybrix designer warns you if a tilemap's dimensions are not Palix-sized. Why allow non-Palix sizes at all? This can be useful for tilemaps that will not be rendered directly by IO_TILEMAP. The idea is to configure IO_TILEMAP with a separate tilemap buffer that is Palix-sized, and then the non-Palix tilemaps get copied into this buffer. For example, the framework's CONSOLE sets up a KERNEL::CONSOLE_GRID buffer for font text. You could make a tilemap that is a dialog box with a non-Palix size, and then at runtime your program could copy it onto the screen. Another common example is an infinite scrolling plane (IO_TILEMAP::EDGE_MODE = 0), where the program generates the tiles interactively as they scroll onto the screen.
I/O definitions
CLASS IO_TILEMAP # SIZE 16
# SCREEN COORDINATES OF UPPER-LEFT CORNER OF TILEMAP
VAR X: PAIR, Y: PAIR
# POSSIBLE VALUES: 16, 32, 64, 128, 256
VAR COL_COUNT: PAIR, ROW_COUNT: PAIR
# A POINTER TO A GRID OF TILE CODES ARRANGED IN LEFT-TO-RIGHT ROWS,
# STARTING FROM THE TOP ROW. THE ARRAY INDEX IS ROW*COL_COUNT+COL.
# EACH TILE CODE IS A 16-BIT PAIR:
# BITS 0..9 ENCODE THE TILE INDEX (0..1023) FROM THE TILESET
# BITS 10..14 ENCODE THE THEME INDEX (0..31) INTO IO::THEMES
# BIT 15 IF SET, IO::MATTE_COLOR REPLACES ANY CLEAR PIXELS IN THIS TILE
VAR TILE_CODES_ADDRESS: INT
# 0 = WRAP: THE MAP WRAPS AROUND, REPEATING INFINITELY IN EVERY DIRECTION
# 1 = CLIP: CELLS OUTSIDE THE MAP BOUNDS ARE TRANSPARENT
VAR EDGE_MODE: BYTE
# ------------------
# TILESET PROPERTIES
# 0 = TILES ARE 8 X 8 PIXELS
# 1 = TILES ARE 16 X 16 PIXELS
VAR JUMBO: BYTE
# 0 < TILE_COUNT <= 1024
VAR TILE_COUNT: PAIR
END CLASS
MODULE IO
. . .
INSET TILEMAP_A: IO_TILEMAP LOCATED AT $D0_0310 # ..$D0_031F
INSET TILEMAP_B: IO_TILEMAP LOCATED AT $D0_0320 # ..$D0_032F
INSET TILEMAP_C: IO_TILEMAP LOCATED AT $D0_0330 # ..$D0_033F
. . .
INSET TILESET_A_ADDRESSES: INT[SIZE 1024] LOCATED AT $D0_1000 # ..$D0_1FFF
INSET TILESET_B_ADDRESSES: INT[SIZE 1024] LOCATED AT $D0_2000 # ..$D0_2FFF
INSET TILESET_C_ADDRESSES: INT[SIZE 1024] LOCATED AT $D0_3000 # ..$D0_3FFF
END MODULE