Palix: themes
The system palette
The system palette is a predefined list of 44 colors, shown below. Index 0 indicates a transparent pixel, so the color indexes are 1 – 44.
0 clear | 1 black | 2 raven | 3 frypan | 4 tinman | 5 pigeon | 6 ghost | 7 white |
8 blush | 9 shrimp | 10 crumpet | 11 slime | 12 iceberg | 13 skyscape | 14 lavendare | 15 mauvelous |
16 red | 17 orange | 18 yellow | 19 green | 20 cyan | 21 blue | 22 purple | 23 violet |
24 rudolf | 25 muffin | 26 goldbar | 27 wasabi | 28 oceana | 29 denim | 30 merlin | 31 potion |
32 chili | 33 mustache | 34 punkin | 35 lawn | 36 sharkfin | 37 sapphire | 38 midnight | 39 saddle |
40 meatloaf | 41 moose | 42 bonbon | 43 offroad | 44 tortoise |
These are called system palette indexes. The other values 45 – 255 will appear as black pixels. (A future version of Hybrix might introduce new colors with indexes 45 – 47, therefore be careful to avoid accidentally using these particular numbers.)
Themes
The system palette colors shown above cannot be modified; no other colors are possible for the Palix video system. However, the color number assignments can be remapped using themes. Themes enable a given sprite or tile image to display different color variations. For example, a chess game might use a theme to determine the color of a chess piece, avoiding the need to create separate sprites for white and black colors. Themes can also be used to create "color cycling" effects such as animating a waterfall or fading the screen to black; a program accomplishes this by writing different values into the io::themes table for each video frame.
The pixel byte array of a sprite or tile therefore does not directly specify a system palette index; instead, it is a theme color index into the io_theme.color_map[] array. If the byte value is greater than 63, it will be masked to 6 bits. (This means bits 6 and 7 of each color byte could be repurposed to store other information such as collision data.)
The io::themes[] array defines 32 themes, identified by a theme index. When the virtual computer first boots, Palix starts with a default theme set, where theme color indexes 0 – 44 correspond exactly to the system palette indexes (except for reversed themes). However, in general a theme can remap any index to any system palette color.
Note that io::background_color and io::matte_color specify system palette indexes, not theme color indexes.
The default theme set
When your program first starts, the themes are initialized as follows:
Themes 0 – 15
- Indexes 0 – 44 map to the corresponding colors from the system palette.
- Index 48, called "color A", has a different color in each theme. Themes 0 through 9 use the corresponding HASCII color.
- Index 49, called "color B", is a darker shade of color A in each theme. It is typically used for shading.
- In theme 15, color A and color B are transparent.
Themes 16 – 31
- These are "reversed" versions of the corresponding themes 0 – 15.
- They are identical to the corresponding theme, except that color #0 (Clear) and color #48 (Theme Color A) are swapped.
- Note that tilemap matte coloring is applied after the palette lookup, therefore "reversed" themes can change which pixels receive the matte color.
- The framework console reverses characters to make the blinking cursor.
- Reversing is also useful with drawing glyphs, for example transforming character #177
▝into▙, or transforming character #185◤into◢.
Your program can customize these mappings by writing to the io::themes array. However, the Hybrix designer always shows the default theme set; it does not yet provide a way to create or preview custom themes. (This may be improved in the future.)
Color A and B
| Theme | Color A | Color B | HASCII | Escape |
|---|---|---|---|---|
| 0 | black (1) | frypan (3) | 16 ($10) | {0} |
| 1 | white (7) | pigeon (5) | 17 ($11) | {1} |
| 2 | red (16) | chili (32) | 18 ($12) | {2} |
| 3 | orange (17) | mustache (33) | 19 ($13) | {3} |
| 4 | yellow (18) | punkin (34) | 20 ($14) | {4} |
| 5 | green (19) | lawn (35) | 21 ($15) | {5} |
| 6 | cyan (20) | oceana (28) | 22 ($16) | {6} |
| 7 | blue (21) | denim (29) | 23 ($17) | {7} |
| 8 | purple (22) | merlin (30) | 24 ($18) | {8} |
| 9 | violet (23) | potion (31) | 25 ($19) | {9} |
| 10 | mustache (33) | meatloaf (40) | ||
| 11 | shrimp (9) | blush (8) | ||
| 12 | crumpet (10) | pigeon (5) | ||
| 13 | slime (11) | green (19) | ||
| 14 | sharkfin (36) | tortoise (44) | ||
| 15 | clear (0) | clear (0) |
I/O definitions
The io_theme class stores an array of 64 bytes, each byte indicating a system palette index. For example, if io_theme.color_map[4] equals 6, that means pixel value 4 should will display color 6 from the system palette (if this theme is active). You can define up to 32 themes and use them in fields such as io_sprite.theme and io_tilemap.tile_codes_address. Thus, the pixel color values that are specified by sprite and tilemap bitmaps are actually theme indexes, not system palette indexes.
class io_theme # size 64
# Maps a theme color index to a system palette index
inset color_map: byte[size 64]
end class
module io
. . .
# Palix video system
var background_color: byte located at $d0_0300
var matte_color: byte located at $d0_0301
. . .
inset themes: io_theme[inset 32] located at $d0_0800 # ..$d0_0fff
. . .
end module
class io_sprite # size 16
. . .
# The theme is an index (0..31) into io::themes
var theme: byte
. . .
end class
class io_tilemap # size 16
. . .
# 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
. . .
end class