Jazz Jackrabbit Cutscene Format
Jazz Jackrabbit cutscenes (.0SC) are the movies played at the end of levels and episodes. They have an exceedingly complex format that has been poorly understood. They contain sound, music, graphics and text. The following snippets of information have been gathered.
There are three headers, only the first being of a fixed size.
0 19 Signature File signature 'Digital Dimensions' + $1A 19 4 Img point Pointer to start of image data header 23 4x + 2 Page header Header for pages ? 4y + 2 Img header Image header
Page and Image headers
0 2 Num Number of entries (Pages or images) in file 2 4x Pointers Pointers to data
These two headers have almost identical formats. The page header stores the pointers to pages or 'scripts' in the cutscene while the graphic header stores the pointers to palettes, still screens and animated screens used by pages. While the length of the page header is always 4 times the number of pages, the graphics header is always much shorter IF there are animated screens. (One pointer to an animated screen can have dozens of animations in it, each counting as one graphic.)
The page, or script is the basic segment of the cutscene. Each page can display some font and a graphic and can transition to other pages. The page data contains a number of sub-segments of varying length that may or may not be present and in various orders.
0 1 Sig Signature 'P' 2 2 Pagenum Page number, as value, not string, starts with $0001 4 2 Pal Palette used 6 ? Segs Optional and vital strings in no particular order ... .. . 1 End End of page data 'E'
Page sub-segments are usually in the following order; in some cases this is necessary (You cannot have a text segment without defining what fonts it can use.) in other cases just the way things are.
Indicates what music file will play during the movie. This is set on the first page only and cannot be changed. Optional, a cutscene may not use music.
0 1 ID Id $2A; this is a music string 1 1 Len Length of music file name 2 len Name Name of music file, inc .PSM
Indicates what fonts will be used in the movie, several allowed. These appear on the first page only and cannot be changed. The value given to each font in this string will be used throughout the movie in font sub-segments. Optional, a cutscene may not use fonts.
0 1 ID Id $58; this is a font string 1 2 Fontnum What number this font is 3 1 Len Length of font name 4 len Name Font name, excluding extension (.0FN added automatically)
Animations and Images
Indicates what graphic is displayed on the page. Vital and each page must have at least one of these. If a page has an animation it will NOT have a text or any image sub-segments
IMAGE 0 1 Img sig Image signature, $46 1 2 h loc Location of image on screen in pixels. For fullscreen images this is 3 2 v loc usually 0,0; for smaller images (rare) this can be anything 5 2 Graphnum Graphic to use, 0 is black screen, palettes cannot be used.
ANIMATION 0 1 Graph sig Graphics signature, $A6 1 4 Anim loop For animated screens, loops the animation. If no loop, page must move on before loop ends or Jazz will crash. Loop value is 1 4 2 Anim sp Animation speed, lower = slower; usually $xx00 6 2 Graphnum Graphic to use, must be an animated screen graphic 8 1 Play sig Ply animation signature, $A7, optional (See following) 9 1 Play For pages that do NOT loop an animation AND do NOT have a set time before they move on (Duration.) this plays the animation then goes to the next page. This can only be 1, otherwise it and its signature are absent
This is really a collection of related segments and signatures. Generally last on the page, these all relate to text strings written on the page. In general you can expect them to start with a 'W' signature, though this is not guaranteed. These do not appear on any page with an animation and are optional.
Signatures can be in any order as long as what they do 'makes sense' (For example you cannot write any text until you've set the font used, the palette zero color AND the justification, but after you have you can write as many lines as you want. You can can change the font used twice without writing anything. You can start a block, write something then start a new block.)
The signatures change values in the movie (All values start at 0) For example the 'F' signature sets the font text is written in. It must be set before text is written and all text following it will use that font until it is reset. Values are not reset when a page is switched, meaning that you can write many pages of text in a font after setting it once.
? 1 Write sig Write signature, "W"; indicates text segment start; there can be more than one segment of text on a page. The following values affect ALL the text in a given text block and always appear in a given order. Note that if a new block starts, ALL values are NOT reset. +1 2 Top margin The page margins; Text cannot normally appear above or left of this location +3 2 Left margin unless this is reset or the text wraps around from the right/bottom of the screen +5 2 Pix h The location of the first line of text, in pixels from the margins. The second +7 2 Pix v value (v) appears not to be read, just the horizontal one, which can, if larger than 320, wrap around and move text vertically (640 moves text down 2 lines...) If this block is not the first block, NEITHER value is read or used!
? 1 Shad sig $DB sets shadows +1 1 Shadow $01 turns shadows on, $00 turns them off. Default is off +2 1 Shad color Palette color used for shadows
? 1 Font sig Change font signature, "F"; indicates what font will be used for the text following +1 2 Font Font used. Must be a valid font number
? 1 Just sig Justification signature "J" +1 1 Just Justification. Text is either left(0) or right(1) aligned; this defines the text start (The position value above reads either left or right.)
? 1 Pal sig Palette zero value signature, "A" +1 2 Pal zero Palette 'zero color'; this value in the palette is set as color 0 for the font; thus the same font can be several different colors depending on its zero color. For example a font pixel $0E can be color $1F or $2E depending on the value (In this case $11 or $20)
? 1 Line sig Sentence signature, "@" +1 1 Length Sentence length, in letters +2 len Text Text, letter displayed is this value's letter in the font file. The value $7F is space. Values over $80 move into the next font (Crashes game if there is no next font.) Thus $81 in font 1 will become $01 in font 2
? 1 Pnum sig Signature for special text, "^" Text that uses this is usually the 'Page x of y' +1 len Length This is the same as the usual text signature stuff, after this a string of text follows. The difference is that values over $89 are allowed and can do special things. $8B is current page number and $8A is the number of pages in the cutscene. $8C is '000' and higher values seem to be '0' Possibly these refer to values in memory.
? 1 Move sig Move line signature, "_" +1 2 Line move Changes the height of all following text lines by this amount, in pixels. Thus if this value is 5, the first line will be 5 pixels lower, the second 10, the 3rd 15... As such it is usually reset to 0 after the desired text is done. This is usually used to position a line of text specially on a background image or relative to other text
The following is a segment of text taken from ORDER.0SC in Jazz CD, starting at position $8A in the file. It is some of the text for the first page of the Order Info cutscene:
57 Text block start sig 14 00 00 00 Location of text left limit, 20 pixels from left of screen 36 01 Font start, 310 pixels BE 01 DB 01 00 Text has shadows of color 0
46 01 00 Font used is font 1 4A 01 Font is aligned right 41 00 00 Font zero color is value 0 5E 0C Special text string follows, 12 characters long 10 1B 21... Text
4A 00 Font aligned left 46 01 00 Font used is font 1 41 00 00 Font zero color = 0 4A 00 Font aligned left 46 02 00 Font used is 2 40 00 Text string follows, 0 long (Move down a line) 40 1D Text string follows, 29 long 7F 7F... 'Had enough excitement...' 40 00 Move down a line 40 1D 7F... 'We didn't think...'
46 01 00 Font used is font 1 40 00 Move down a line 40 1D 7F 'You are playing...'
There are a number of less complex segments that may appear on each page.
Screen transition segment 0 1 Sig Screen transition signature $3F 1 1 Trans Transition, 0 = none, 1 = speckle 2 = circle
Page duration segment 1 1 Sig Signature ']' 2 1 Duration How long in seconds page stays before transitioning to next page
Music transition segment 1 1 Sig Signature, 'Q' 2 1 Music trans Music transition, $2D stops music on page transition
Yes/no input segment 1 1 Sig Signature $23, if present page accepts only "y" or "n" as input and will switch to the next page ONLY if "y" is pressed, otherwise the movie will end
??? 1 1 ??? Signature '>'; apparently does something unknown
There are three kinds of graphic, palette, still screen and animated screen. Each has its own unique format.
The palette is the 256 colors used by a screen to display graphics and fonts. A page may only use one palette but a cutscene can have several. Palettes are Jazz Jackrabbit RLE compression compressed and decompress to 768 bytes in length, 256 3-byte RGB values. (The same format as palette blocks in other Jazz files such as Jazz Jackrabbit Tile Format Palettes are 6-bit stored as 8-bit, so each value must be multiplied by four to get the 'true' color for bitmaps.
Palettes are usually the first graphics entries.
These are 320x200 images that fill an entire screen and act as the background to a page. Like palettes they are Jazz Jackrabbit RLE compression compressed, but decompress to 64'004 bytes in length. Note that while other image sizes are possible, in practice only fullscreen images are seen.
0 2 Width Width of following screen 2 2 Height Height of following screen 4 hw Data Screen data
These are 320x200 images that animate. They cannot have font displayed over them and are the traditional 'movie' part of Jazz cutscenes. Their format is complex and poorly understood but relies on at least two forms of unique RLE compression. There is a header followed by a start image compressed in one way, followed by a number of 'frames' compressed in another manner.
0 2 Sig Signature 'AN' 2 2 ? Must be $0002? 4 2 ? Is always $0007? 6 2 Pal sig Palette signature 'PL' 8 2 Palsize Size of following unused palette (Always $300) 10 768 Palette Unused(?) palette, uncompressed 778 ? Anim st Animation start image ? ? Anims Following animation frames ... .. . ? 4 End End of anim sequence, $5F $45 $00 $00 '_E '
Animation Start Image
This image is written onto a 'blank' screen when a page is started and the other animations work by overwriting this. In many cases it works like the 'background' of a .GIF image. The data will ALWAYS decompress to a 64'000 byte fullscreen image.
The way the image is drawn however is interesting. Instead of drawing each line pixel by pixels as static screens to, when a pixel of a given color is drawn, all the pixels directly beneath it will be colored the same. This is a great space saver; instead of coloring all of the background of an image blue, for example, only the first line must be blue; all the other lines below it will then be this color as well.
An image is built up by lower lines overwriting earlier ones, line by line. In the image left the first row of the image has been changed from black to pink, also changing all the columns under it to pink. Lower lines overwrite this with other colors, thus building up the image.
Color 255 ($FF) is 'transparent'; in practice this means 'skip over this column, it's already the right color' In our 'blue screen' example above, all the other rows would be colored transparent, since the entire screen would be blue and we wouldn't want to change that. In the example image above all the pink columns have been skipped over until another color was needed. It is possible to show the exact same image by replacing the transparent pixels with the value of the pixel above them, but this takes up a lot more space and takes longer to draw.
Format: 0 2 Set screen What to do to the screen before the image is displayed. $3131 is 'rle image' $4c31 means use other form of compression for image $4646 means 'leave as is' This image usually uses 'reset'; clearing the screen and writing the image on it 2 2 Anim size Size of animation data to follow 4 ? data Image data
The compression used on the first image can be either normal Jazz Jackrabbit RLE compression ($3131 tag) or a more complex form of the usual ($4c31 tag), with a wider variety of control bytes. It may be considered to contain elements or RLEW as well. The upshot of this is to allow a large image to be compressed rather more efficiently than standard RLE. The types of control bytes are as follows for this format:
$0x $... Next x + 1 bytes are 'literals'; each byte colors 1 column (Max val $3F) $4x $yy Next x + 1 columns drawn in color yy (Max value $7E) $7F $xxxx $yy Next xxxx columns colored with color yy $8x Next x + 1 pixels are skipped, they're already the right color (Max val $FE) $FF $xxxx Skip next xxxx pixels of picture, they're already the right color
These follow the first image and are usually compressed to much smaller sizes as they involve changes to the previous screen rather than drawing a whole new screen. They are either a fullscreen frame (type $5b5d( ][ )) using the alternative compression mode used in the start image or a modified form of the animation start compression that has not yet been figured out(type $4646(FF) and type $4352(RC)).
The frame is drawn by taking the previous screen and drawing the changes over it. In the example picture right the second animation frame has been moved left by 200 pixels so it is written over a black background. It can bee seen how little of the image has been changed and also how much of it is transparent. (In the middle of the smoke this is most easily seen where black pixels show where the previous screen had the right color grays not to need changing.)
It can also be seen that an animation can erase a previous frame by changing pixels back to what they were previously. In the example image some smoke fragments are visible because they have not been overwritten.
If the animation isn't 'fullscreen' then when decompressed it does not have to be 64'000 long (320x200) While the animation starts drawing at 0,0 it can finish anywhere. In the example above the changes finish about 1/3 way down the screen, so the decompressed data is about 20'000 bytes long. Another thing to note is that unlike still screens, images are filled in row-by-row, without columns being filled.
Format: 0 2 Set screen Almost always $4646, 'leave previous screen' 2 2 Anim size Size of animation data to follow 4 ? data Image data
The compression used in animation frames is not the same as that of the first image, though it appears similar. The first complication is at the first byte. If this is $FF then it is normal data and the image should be read normally. (That is $FF is a control byte and should be treated as such.) If it is not, then the first byte is the x location to start drawing the image (on the first line, that is it can be said to stand for 'x pixels of transparent color'.)
There are 5 types of control byte. The highest bit of control bytes indicates what to set the 'transparency flag' to (1 on; 0, off) while the next two define what the control byte does. The fourth bit may not have a function, and the lower four bits are the number of pixels of image to be affected.
There are two 'special cases'; $00 and $7F\$FF. The first stops decompression and the second is used for long stretches of transparent pixels.
There are a number of complicated rules that have yet to be worked out. Some control bytes that set the 'T-flag' to on must be preceeded by a control byte that does the same thing, it is not known why. Some values ($80, $7F, $Ex) are not used or have not yet been observed
A basic summary of this is as follows; 'T-flag' indicates what the transparency flag is set to after the control byte is read. 'H-flag' indicates whether the control byte must be preceded by a control byte that has its highest bit set to 1.
|0||Output next byte as literal and STOP||ON||NO|
|0x,8x||If T-flag ON, x transparent pixels follow. If T-flag OFF, read next x bytes and output||FLIPPED||NO|
|2x||Copy xx&0x1f pixels from the line above||ON||NO|
|4x||Read next byte as colour to fill with, repeat 0xvalue&0x1f times||ON||NO|
|7F||Read next word (add 255 if trans on), output that many bytes of transparent||ON||NO|