Mode 41 guide
Video Mode 41 is a simple attribute mode which most commonly could be used to produce 40 x 25 tile colored text or ASCII / ANSI graphics displays, reproducing similar look & feel games like text mode games on old 8 / 16 bit computers.
The best way to begin is to copy the [Mode 41 example] from the Uzebox master repo, and start off from that. It contains easy to activate examples for most of the mode's features.
The Video & Attribute RAM
When using the mode in its default configuration (40 x 25 tiles), you have got 1000 bytes (40 x 25) of VRAM which can be accessed by the Uzebox kernel's functions (so you can use Print and similar functions on it) and 1000 bytes (40 x 25) of ARAM (Attribute RAM) which specifies the Foreground colors for each tile. By default the Background is Black and the Foreground is filled with White (so even without initializing the ARAM, you will see your text output).
The character sets are contained in ROM. You don't need to provide them if you don't want to: the mode already contains some which you can activate with Makefile flags. This mode uses the same character set definitions like Mode 40. Note that the definitions are carried over from Mode 40 (so they are like M40_xxx and the arrays are m40_xxx).
If you want to generate character sets, use [the generator] provided with Mode 40, it can convert Gimp exported headers to suitable C arrays.
Mixing character sets
Every tile row can have its own character set, you can set the character set using SetTileTableRow(). You can access the included character sets with the lowercase equivalent of the Makefile definitions (for example call SetTileTableRow(m40_c64_mixed, 10); to set Row 10 to Commodore 60 PETSCII Mixed, of course only works if you enabled that character set).
The mode provides simple blocky graphics display too which you can enable with the M41_TILEROW_1BPP or the M41_TILEROW_2BPP special character set codes (you can supply them to SetTileTable() to set the entire screen or SetTileTableRow() to set individual rows. They use the same VRAM and ARAM regions like the normal character mode.
The individual pixels of these modes can be accessed by the PutPixel and the GetPixel functions.
If you want to do something more advanced with them, you can do direct access, keeping in mind that the pixel layout is a little "weird".
1 bit per pixel mode layout
In 1 bit per pixel mode the ARAM and the VRAM contains pixel values. The background color is taken from 'palette' and the foreground is taken from 'palette'. There are 4 bitmap rows in a tile row which get their pixels as follows:
- Row0: aram[tile].bit0, aram[tile].bit1, aram[tile].bit2, aram[tile].bit3
- Row1: aram[tile].bit4, aram[tile].bit5, aram[tile].bit6, aram[tile].bit7
- Row2: vram[tile].bit0, vram[tile].bit1, vram[tile].bit2, vram[tile].bit3
- Row3: vram[tile].bit4, vram[tile].bit5, vram[tile].bit6, vram[tile].bit7
2 bits per pixel mode layout
In 2 bits per pixel mode the ARAM and VRAM both contains pixel values, specifying color indices from 0 - 3 which colors are fetched from 'palette'. This is a planar mode where each byte specifies the pixels of a bitplane:
- Bitplane 0: aram[tile]
- Bitplane 1: vram[tile]
The pixel bit positions of each byte are laid out in the 4 bitmap rows as follows:
- Row0: bit0, bit1
- Row1: bit2, bit3
- Row2: bit4, bit5
- Row3: bit6, bit7
Screen sizes can be configured identically to Mode 40.
Different background for every line
By calling SetBackgroundPerLine(1) you can enable loading a new background color into 'palette' at every scanline. The background colors are taken from the 'bgcolor' array, this array has the size VRAM_TILES_V * TILE_HEIGHT.