Skip to content

Advanced Drawing Techniques

Damien de Lemeny edited this page May 27, 2020 · 13 revisions

0x03FF0 Palette Map / Swapping colors

Usage

poke4(2*0x03FF0 + color_index, mapped_color_index)
memset(0x03FF0, palette_map, 8)

Description

+-------+-------------------+-------+
| ADDR  | INFO              | SIZE  |
|-------+-------------------+-------|
| 00000 | SCREEN            | 16320 | 240x136 = 32640 4bit pixels
| 03FC0 | PALETTE           | 48    | 16 x 24bit RGB color values
| 03FF0 | PALETTE MAP       | 8     | 16 x 4bit color indexes (for palette swapping of individual sprites)
+-------+-------------------+-------+

TIC-80 uses PALETTE MAP to swap 4 bits colors indices to be drawn to any combination of 4 bits colors in the palette. The mapped 4 bits color is written on SCREEN.

With sprite-drawing functions (spr, map, textri), this color swap is done when reading the color from sprite memory.

colorkey parameters are applied on source colors, swapping out color indices before remapping.


0x03FFC Blit Segment / Low BPP graphics ([BETA FEATURE, spec might change before release]0.80)

Usage

poke4(2*0x03FFC, blit_segment)

Description

The blit segment controls how sprite drawing functions will read sprites in memory. It can specify the amount of bits to read per pixel and the position of the spritesheet.

Total indexing VS local indexing

In TIC-80, sprite drawing functions use two different types of indexing:

  • total indexing: spr indexes sprites counting 8x8 sprite positions from left to right and from top to bottom on the whole spritesheet
  • local indexing: map, textri with use_map=true and font use 8 bit unsigned integer as indexes. This difference is the reason why those functions are limited to a portion of the spritesheet.

The blit segment modifies how indexes are interpreted.

Simplified spec for total indexing

val | bin  | target memory segment
-------------------------- 
2  | 0010 | 4bpp  // default value
4  | 0100 | 2bpp
8  | 1000 | 1bpp
Index Stretching
4 bpp                      2 bpp                        1 bpp
 <-------16 cols------->    <--------32 cols-------->    <---------64 cols--------->
+------+---------+------+  +------+-----------+------+  +------+------+------+------+
| 0000 |         | 0015 |  | 0000 |           | 0031 |  | 0000 |             | 0063 |
+------+--     --+------+  +------+--       --+------+  +------+--         --+------+
|                       |  |                         |  |                           |
:       TILES (BG)      :  :        TILES (BG)       :  :         TILES (BG)        :
|                       |  |                         |  |                           |
+    --+--     --+------+  +    --+--       --+------+  +    --+--         --+------+
|                | 0255 |  |                  | 0511 |  |                    | 1023 |
+------+---------+------+  +------+-----------+------+  +------+-------------+------+
| 0256 |         | 0271 |  | 0512 |           | 0527 |  | 1024 |             | 1087 |
+------+--     --+------+  +------+--       --+------+  +------+--         --+------+
|                       |  |                         |  |                           |
:      SPRITES (FG)     :  :       SPRITES (FG)      :  :        SPRITES (FG)       :
|                       |  |                         |  |                           |
+    --+--     --+------+  +    --+--       --+------+  +    --+--         --+------+
|                | 0511 |  |                  | 1023 |  |                    | 2047 |
+------+---------+------+  +------+-----------+------+  +------+------+------+------+

Origin translation and local indexing window

The blit_segment can be used to give functions using local indexing access to the full spritesheet using origin translation. blit_segment values define actually define both the way to read pixels and a virtual window in memory.

Because local indexing considers a 16 columns grid, low bpp spritesheets are organized in pages of 16 columns, laid out horizontally. The blit segment defines which page will be read.

Also, because both indexing schemes should be usable for any value of blit_segment, origin translation is also applicable to total indexing. The spritesheet wraps around on both vertical and horizontal axis, and the blit segment defines where the indexing starts.

Full blit_segment specification

val | bin  | target memory segment
-------------------------- 
0   | 0000 | (reserved)
1   | 0001 | (reserved)
2   | 0010 | 4bpp page 0 BG  // default value
3   | 0011 | 4bpp page 0 FG
4   | 0100 | 2bpp page 0 BG
5   | 0101 | 2bpp page 0 FG
6   | 0110 | 2bpp page 1 BG
7   | 0111 | 2bpp page 1 FG
8   | 1000 | 1bpp page 0 BG
9   | 1001 | 1bpp page 0 FG
10  | 1010 | 1bpp page 1 BG
11  | 1011 | 1bpp page 1 FG
12  | 1100 | 1bpp page 2 BG
13  | 1101 | 1bpp page 2 FG
14  | 1110 | 1bpp page 3 BG
15  | 1111 | 1bpp page 3 FG
Clone this wiki locally