+==========================================================================================+ |Jazz Jackrabbit Sprite Gaphics format: | +==========================================================================================+ Sprites for Jazz Jackrabbit are stored in SPRITES.xxx and MAINCHAR.000 files. SPRITES.xxx contains all sprites that belong to levels LEVELy.xxx with tileset BLOCKS.xxx. MAINCHAR.000 contains all standard sprites, such as Jazz's walking animations and such. When a level is loaded, sprites are loaded into a 256-sprite array. First the MAINCHAR is read, then the level's SPRITES file. Both files contain 'holes' or null entries that can be filled by the other. (For example, MAINCHAR has holes between 23-48 and 238-255) If a sprite exists in both files, the SPRITES one is loaded. This produces a sprite array for each level containing 238-256 sprites, with a number of 'holes' that can also be used by events. (Nothing will appear, and this is used in several ingenious ways.) Sprite files (Except MAINCHAR) have a header, followed by three different types of sprite 'entry' Note that there is a sprite zero. ------------------------------------------------------------------------------- FILE STRUCTURE: HEADER (Absent in MAINCHAR) SPRITE ENTRIES ... .. . ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- Header: 0 2 Numsp Number of sprites in file 2 x h off Horizontal offset of sprites. This segment is [Numsprites] bytes long consisting of one-byte entries for each sprite loaded in-level including those in MAINCHAR.000 and 'null' sprites. The minimum size of this is thus 237 bytes. (Max 256) x + 2 x v off Same format and size as above, but more significant. Both these segments provide x,y co-ords for the start of each sprite in the file, used to 'line up' sprites of different heights and widths for animations. ------------------------------------------------------------------------------- Sprite entries come in three types, blank, masked and 'unmasked' as follows: ------------------------------------------------------------------------------- Blank sprite entry: 0 2 Value $FFFF, indicates sprite is a blank palceholder. ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- 'Unmasked' sprite entry: 0 2 Sprite width \ 4 2 2 Sprite height 4 2 Image size, sprite is made out of FOUR of these images, interlaced 6 2 Size of mask data segment, zero. 8 2 'Pixel data' size $FFFF to indicate sprite is 'unmasked' 10 x Image 1,2,3,4... The sprite is divided into columns, image 1 consists of columns 1,5,9..., image 2 consists of columns 2,6,10... and so on. This is quite common in Jazz. 1-byte values here are the color of each pixel, 254 being transparent and 255 being unuseable. ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- Masked sprite entry: 0 2 Sprite width \ 4 2 2 Sprite height (Excluding extra height) 4 2 Image size, [Height] + 1 * [width] 6 2 Size of mask data segment 8 2 Pixel data size, number of nonzero-value pixels in sprite mask, the total 'Pixel data' size will be four times this value. 10 2 * h Mask data, 2 bytes per line of mask; notes the sum of how many masked pixels are in the mask so far. The last entry will thus be the same as the [Pixel data size] (Total number of masked pixels.) and the first entry will be pretty low. JAZZ doesn't read this, but it is (was) used by Epic to figure out the h\v offsets earlier. ~2h w * h Squashed sprite mask, each byte is worth four pixels of sprite. Values are between 0-15, with the last four bits of each byte controlling whether the four pixels are masked, and in what order. ~w+2h 4 * pd Pixel data 1,2... The color of each pixel of the sprite. The decompressed mask is divided into columns, much like the 'unmasked' sprites above. This data then controls the color of each column. Since the mask has an entry for every four pixels, this will occasionally need a color entry for a pixel that is not supposed to be masked color 254 is used for this. (However, zero value mask entries aren't given any data here.) This is difficult to envision without a diagram. -------------------------------------------------------------------------------