Image Formats: Difference between revisions
Created page with "Weissblatt uses custom image formats for it's sprites, graphics and textures, which it inherited and extended from Doom (1993). All of these formats are ''paletted'', meaning they require a Color Palette to be rendered properly. == Flat == ''Flats'' are textures used for floors and ceilings. The file format is a simple dump of palette indices. Doom originally required these to be 64x64 pixels in size, but Weissblatt supports any..." |
|||
| (5 intermediate revisions by the same user not shown) | |||
| Line 19: | Line 19: | ||
When rendered in-game, only the red channel is considered when dereferencing colors, with the value of the red channel serving as transparency or ''alpha channel'' for rendering the screen transition. For convenience, most artists prefer to draw screen fades as paletted grayscale images. | When rendered in-game, only the red channel is considered when dereferencing colors, with the value of the red channel serving as transparency or ''alpha channel'' for rendering the screen transition. For convenience, most artists prefer to draw screen fades as paletted grayscale images. | ||
When importing screen fades into your [[PK3]], it must be rendered into individual frames | When importing screen fades into your [[PK3]], it must be rendered into individual frames matching the file names <code>FADExxyy</code>, with <code>xx</code> standing for the screen fade number and <code>yy</code> standing for the frame number. All frames must then be placed <u>in a contiguous, numerically ordered list</u> under <code>Fades/</code>. Not maintaining continuity and/or numerical order will result in errors. | ||
== Picture Format == | == Picture Format == | ||
''Reference: [https://doomwiki.org/wiki/Picture_format Picture format on Doom Wiki]'' | |||
''Doom pictures'' are used for UI graphics, patches, sprites and wall textures. The file format is ''column-oriented,'' with each column being composed of zero or more ''posts'', which are basically arrays of pixels. These posts are assembled into a column based on their lengths and offsets. Each column starts at an offset defined in the header and is terminated by a byte containing <code>0xFF</code>. | |||
=== Headers === | |||
Each Doom picture starts with a header, indexing the offsets of each column. When a picture is rendered, the engine starts drawing each column at the offset given in <code>columnofs</code> and draws all posts it finds until the next column starting with <code>0xFF</code> (column terminator byte). | |||
{| class="wikitable" | |||
|+ | |||
Patch header data structure | |||
!Field | |||
!Type | |||
!Byte size | |||
!Byte offset | |||
!Description | |||
|- | |||
|width | |||
|uint16_t | |||
|2 | |||
|0 | |||
|Graphic width (Little Endian) | |||
|- | |||
|height | |||
|uint16_t | |||
|2 | |||
|2 | |||
|Graphic height (Little Endian) | |||
|- | |||
|leftoffset | |||
|int16_t | |||
|2 | |||
|4 | |||
|Pixel offset from the left side (Little Endian) | |||
|- | |||
|topoffset | |||
|int16_t | |||
|2 | |||
|6 | |||
|Pixel offset from the top (Little Endian) | |||
|- | |||
|columnofs | |||
|uint32_t[] | |||
|4 * width | |||
|8 | |||
|Array of column offsets relative to the beginning of this header (Little Endian) | |||
|} | |||
=== Posts === | |||
''Posts'' are one-dimensional strips of palette indices with a length and a top offset or ''top delta'' attached: | |||
{| class="wikitable" | |||
|+Post data structure | |||
!Field | |||
!Type | |||
!Byte size | |||
!Byte offset | |||
!Description | |||
|- | |||
|topdelta | |||
|uint8_t | |||
|1 | |||
|0 | |||
|Post offset from top | |||
|- | |||
|length | |||
|uint8_t | |||
|1 | |||
|1 | |||
|Post length | |||
|- | |||
|''padding'' | |||
|uint8_t | |||
|1 | |||
|2 | |||
|Unused padding byte. | |||
|- | |||
|data | |||
|uint8_t[] | |||
|length | |||
|3 | |||
|Array of palette indices | |||
|- | |||
|''padding'' | |||
|uint8_t | |||
|1 | |||
|3 + length | |||
|Unused padding byte | |||
|} | |||
=== Tall patches === | |||
''Tall patches'' are a backwards-compatible hack to allow Doom pictures larger than 256 pixels in height. Since Doom pictures can theoretically be up to 65536x65536 pixels large, yet posts can only be up to 254 pixels long (with the byte value <code>255</code> serving as a terminating byte per-post), vanilla Doom pictures can practically only be 65536x508 pixels large. Tall patches hack around this limit by placing posts beyond <code>y=255</code> relatively to one another, theoretically allowing for an infinite vertical size. | |||
In a Doom engine supporting tall patches, whenever a post's top delta is less than it's predecessor's top delta, an overflow is detected and both values are added together for the new top delta to allow for the tall patch. This makes top offsets beyond 254 effectively relative to one another, rather than absolute as before. | |||
In a Doom engine ''not'' supporting tall patches, the posts in question will simply wrap and draw over the existing sprite space. | |||
Many tools like [https://slade.mancubus.net/ SLADE] and [https://github.com/liquidunderground/pk3make PK3Make] will also automatically insert zero-length pseudo patches at top delta 254 during image conversion to guarantee a reliable detection of tall patches. | |||
[[Category:Technology]] | |||
Latest revision as of 03:06, 7 June 2025
Weissblatt uses custom image formats for it's sprites, graphics and textures, which it inherited and extended from Doom (1993). All of these formats are paletted, meaning they require a Color Palette to be rendered properly.
Flat[edit | edit source]
Flats are textures used for floors and ceilings. The file format is a simple dump of palette indices. Doom originally required these to be 64x64 pixels in size, but Weissblatt supports any square size between 1x1 and 2048x2048.
Fade[edit | edit source]
The screen fade format is identical to flats; a simple dump of palette indices. Sizes are required to be one of the following:
| Image Size |
|---|
| 80x50 |
| 160x100 |
| 320x200 |
| 640x400 |
When rendered in-game, only the red channel is considered when dereferencing colors, with the value of the red channel serving as transparency or alpha channel for rendering the screen transition. For convenience, most artists prefer to draw screen fades as paletted grayscale images.
When importing screen fades into your PK3, it must be rendered into individual frames matching the file names FADExxyy, with xx standing for the screen fade number and yy standing for the frame number. All frames must then be placed in a contiguous, numerically ordered list under Fades/. Not maintaining continuity and/or numerical order will result in errors.
Picture Format[edit | edit source]
Reference: Picture format on Doom Wiki
Doom pictures are used for UI graphics, patches, sprites and wall textures. The file format is column-oriented, with each column being composed of zero or more posts, which are basically arrays of pixels. These posts are assembled into a column based on their lengths and offsets. Each column starts at an offset defined in the header and is terminated by a byte containing 0xFF.
Headers[edit | edit source]
Each Doom picture starts with a header, indexing the offsets of each column. When a picture is rendered, the engine starts drawing each column at the offset given in columnofs and draws all posts it finds until the next column starting with 0xFF (column terminator byte).
| Field | Type | Byte size | Byte offset | Description |
|---|---|---|---|---|
| width | uint16_t | 2 | 0 | Graphic width (Little Endian) |
| height | uint16_t | 2 | 2 | Graphic height (Little Endian) |
| leftoffset | int16_t | 2 | 4 | Pixel offset from the left side (Little Endian) |
| topoffset | int16_t | 2 | 6 | Pixel offset from the top (Little Endian) |
| columnofs | uint32_t[] | 4 * width | 8 | Array of column offsets relative to the beginning of this header (Little Endian) |
Posts[edit | edit source]
Posts are one-dimensional strips of palette indices with a length and a top offset or top delta attached:
| Field | Type | Byte size | Byte offset | Description |
|---|---|---|---|---|
| topdelta | uint8_t | 1 | 0 | Post offset from top |
| length | uint8_t | 1 | 1 | Post length |
| padding | uint8_t | 1 | 2 | Unused padding byte. |
| data | uint8_t[] | length | 3 | Array of palette indices |
| padding | uint8_t | 1 | 3 + length | Unused padding byte |
Tall patches[edit | edit source]
Tall patches are a backwards-compatible hack to allow Doom pictures larger than 256 pixels in height. Since Doom pictures can theoretically be up to 65536x65536 pixels large, yet posts can only be up to 254 pixels long (with the byte value 255 serving as a terminating byte per-post), vanilla Doom pictures can practically only be 65536x508 pixels large. Tall patches hack around this limit by placing posts beyond y=255 relatively to one another, theoretically allowing for an infinite vertical size.
In a Doom engine supporting tall patches, whenever a post's top delta is less than it's predecessor's top delta, an overflow is detected and both values are added together for the new top delta to allow for the tall patch. This makes top offsets beyond 254 effectively relative to one another, rather than absolute as before.
In a Doom engine not supporting tall patches, the posts in question will simply wrap and draw over the existing sprite space.
Many tools like SLADE and PK3Make will also automatically insert zero-length pseudo patches at top delta 254 during image conversion to guarantee a reliable detection of tall patches.