Various file formats used across projects.
ICN is a 1-bit graphics format.
The ICN
file contains a series of bits equivalent to pixels in a 8x8 tile. The data for each tile is made up of 64 bits, or 8 bytes, in which each bit is a pixel. An ICN is the first half of a chr file. This is the standard format for Varvara ecosystem, to view and edit icn files, try Noodle.
ch1 | hex | |||||||
---|---|---|---|---|---|---|---|---|
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 00 |
0 | 0 | 1 | 1 | 1 | 1 | 0 | 0 | 3c |
0 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 42 |
0 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 7e |
0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 40 |
0 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 42 |
0 | 0 | 1 | 1 | 1 | 1 | 0 | 0 | 3c |
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 00 |
Example
24x24 ICN Sprite | |
---|---|
![]() |
0003 6331 397b 77f8 c0f0 f7ff fff0 8003 1c7e feff 0f07 078e f860 0c07 0300 301f 071f 7cf8 f007 7fff dcc0 c000 70f8 f8b0 0f07 4143 677f 7f3e ffe3 87cf cfcf 8703 84c4 8406 0efe fcf8 |
Implementation
Uint8 tile[8] = {0x00, 0x3c, 0x42, 0x7e, 0x40, 0x42, 0x3c, 0x00}; void draw_icn(Uint32 *dst, int x, int y, Uint8 *sprite, int fg, int bg) { int v, h; for(v = 0; v < 8; v++) for(h = 0; h < 8; h++) { int ch1 = (sprite[v] >> (7 - h)) & 0x1; put_pixel(dst, x + h, y + v, ch1); } }
- ICN/CHR Toolchain, viewer and converter.
CHR is a 2-bit graphics format.
The CHR
file contains a series of bits equivalent to pixels in a 8x8 tile. The data for each tile is made up of 128 bits, where the first 64 bits are the first channel, the next 64 bits the second channel, and where the channels overlap result in a total of 4 colors including the background.
ch1 + ch2 | hex | ||||||||
---|---|---|---|---|---|---|---|---|---|
1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | f8 | 00 |
1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | f8 | 00 |
1 | 1 | 3 | 3 | 3 | 2 | 2 | 0 | f8 | 3e |
1 | 1 | 3 | 3 | 3 | 2 | 2 | 0 | f8 | 3e |
1 | 1 | 3 | 3 | 3 | 2 | 2 | 0 | f8 | 3e |
0 | 0 | 2 | 2 | 2 | 2 | 2 | 0 | 00 | 3e |
0 | 0 | 2 | 2 | 2 | 2 | 2 | 0 | 00 | 3e |
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 00 | 00 |
This is the standard format for the Famicom and Varvara ecosystems, to view and edit chr files, try Nasu. To convert images from the tga format, use tgachr.
Uint8 tile[16] = { 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x00 }; void draw_chr(Uint32 *dst, int x, int y, Uint8 *sprite) { int v, h; for(v = 0; v < 8; v++) for(h = 0; h < 8; h++) { int ch1 = ((sprite[v] >> h) & 0x1); int ch2 = (((sprite[v + 8] >> h) & 0x1) << 1); put_pixel(dst, x + 7 - h, y + v, ch1 + ch2); } }
- ICN/CHR Toolchain, viewer and converter.
NMT is a 2-bit graphics nametable format.
The NMT
file contains a series of cells referencing addresses to sprites in a spritesheet, typically icn tiles or chr tiles. A cell is 3 bytes long, the first two bytes are the address starting from the beginning of the spritesheet, followed by a color byte. This format is used in Nasu.
Cell(3 bytes) | |
---|---|
Addr* | color |
GLY is a 1-bit graphic format for Uxn glyphs.
Gly is an inline graphics format used to draw 1-bit glyphs inside of ascii text, in which each byte is used to represent 4 vertical pixels. Glyphs are supported by Left, and can be generated in Noodle.
ascii | x+1 | y*4 | 4 pixels | ||||
1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
The format resides entirely in the second half of the ascii table, or above $80. At the end of each row, the character 0a denotes the end of line, a 32px high sprite, will have two line breaks. The Y bit shifts the pixels drawing by 4 pixels vertically for a total of 16 vertical pixels, the X bit advances the rendering by 1 pixel horizontally.
GLY Example
32x32 Sprite | |
---|---|
![]() |
9faf ff88 e384 98e2 8294 e281 96a2 fe8f 97e2 97a2 fc88 95a2 f284 95a2 fc82 95e2 8195 a2fe 8195 e281 95a2 fe81 95e2 8195 a2fc 8195 a2f2 8195 a2fc 8195 e281 95a2 fe81 95e2 8195 e281 95e2 8195 aeff 8195 e581 9de8 8195 f181 93f2 8191 f189 92e8 8594 acff 8398 e281 e10a 8f9f afff f8f8 f889 97ac f8a2 f988 97ac f881 f893 aef9 8894 f881 93ac f8a2 f989 97ac f8f8 8897 acf8 81a2 f993 acf8 8894 f881 93ae f9f8 f8f8 8f9f afff f4f2 f1e8 e4e2 8f9f e1c0 c00a |
Draw a character's glyph in Uxntal when the screen's auto byte is set to auto-y
:
@draw-gly ( char color -- ) STH STH .Screen/y DEI2 ( y ) #00 STHkr #30 AND #24 SFT OVR2 ++ .Screen/y DEO2 #0400 &loop STHkr #0f AND OVR SFT #01 AND ( pixel ) OVRr STHr #00 ! * .Screen/pixel DEO INC GTHk ,&loop JCN POP2 .Screen/y DEO2 ( x ) NIPr STHr #06 SFT #01 AND JMP RTN .Screen/x DEI2k INC2 ROT DEO2 RTN
UFX is a proportional font format.
The UFX
file begins with 256 bytes corresponding to the width(in pixels) of each of the 256 glyphs in the spritesheet, followed by the pixel data in the .icn format for each character.
Extension | Size(px) | Filesize |
---|---|---|
.uf1 | 8x8(1 tile) | 0x0900 |
.uf2 | 16x16(4 tiles) | 0x2100 |
.uf3 | 24x24(9 tiles) | 0x4900 |
The pixel data for each glyph is stored in a series of 8x8 tiles, the drawing order goes vertically as to be able to skip extra draw calls for narrow characters if needed:
0 | 2 |
1 | 3 |
A naive uf2 character drawing routine in Uxntal is about 50 bytes, with the screen's auto byte set to #15
:
@draw-uf2 ( text* -- ) #15 .Screen/auto DEO &while LDAk #20 SUB #00 SWP DUP2 #50 SFT2 ;font/glyphs ADD2 .Screen/addr DEO2 ;font ADD2 LDA #00 SWP .Screen/x DEI2 ADD2 #01 .Screen/sprite DEOk DEO .Screen/x DEO2 INC2 LDAk ,&while JCN POP2 JMP2r
The empty pixel data of the first 32 invisible characters are typically removed. You will find this filetype in the Uxn ecosystem, namely in Left. Uf2 fonts can be viewed and edited with Turye.
Truevision TGA is a raster graphics file format created by Truevision.
TGA files are currently used as the standard image transfer format between Varvara and the host operating system.
Length | Field name | Description |
---|---|---|
1 byte | ID length | Length of the image ID field |
1 byte | Color map type | Whether a color map is included |
1 byte | Image type | Compression and color types |
5 bytes | Color map specification | Describes the color map |
Specification | ||
2 bytes | X-origin | absolute x of lower-left corner |
2 bytes | Y-origin | absolute y of lower-left corner |
2 bytes | Image width | width in pixels |
2 bytes | Image height | height in pixels |
1 byte | Pixel depth | bits per pixel |
1 byte | Image descriptor | bits 3-0 give the alpha channel depth, bits 5-4 give direction |
Image ID length
0–255 The number of bytes that the image ID field consists of. The image ID field can contain any information, but it is common for it to contain the date and time the image was created or a serial number.
Color map type
- 0 if image file contains no color map
- 1 if present
- 2–127 reserved by Truevision
- 128–255 available for developer use
Image type
Enumerated in the lower three bits, with the fourth bit as a flag for RLE. Some possible values are:
- 0 no image data is present
- 1 uncompressed color-mapped image
- 2 uncompressed true-color image
- 3 uncompressed black-and-white (grayscale) image
- 9 run-length encoded color-mapped image
- 10 run-length encoded true-color image
- 11 run-length encoded black-and-white (grayscale) image
Image type 1 and 9: Depending on the Pixel Depth value, image data representation is an 8, 15, or 16 bit index into a color map that defines the color of the pixel. Image type 2 and 10: The image data is a direct representation of the pixel color. For a Pixel Depth of 15 and 16 bit, each pixel is stored with 5 bits per color. If the pixel depth is 16 bits, the topmost bit is reserved for transparency. For a pixel depth of 24 bits, each pixel is stored with 8 bits per color. A 32-bit pixel depth defines an additional 8-bit alpha channel. Image type 3 and 11: The image data is a direct representation of grayscale data. The pixel depth is 8 bits for images of this type.
Color map specification
- First entry index (2 bytes): index of first color map entry that is included in the file
- Color map length (2 bytes): number of entries of the color map that are included in the file
- Color map entry size (1 byte): number of bits per pixel
In case that not the entire color map is actually used by the image, a non-zero first entry index allows to store only a required part of the color map in the file.