Jazz Jackrabbit 2 J2V

From MultimediaWiki
Jump to navigation Jump to search

This is an animation format used in Jazz Jackrabbit 2 game.

Header format:

 8 bytes - "CineFeeed"
 4 bytes - file size
 4 bytes - CRC
 4 bytes - width
 4 bytes - height
 2 bytes - depth (should be 8)
 2 bytes - delay between frames in milliseconds
 4 bytes - number of frames
 20 bytes - some sizes

Frame data is split into four streams with different kinds of data (a la Smacker or Bink), each compressed with deflate independently and with chunks containing data for one or more frames being output time from time. Decoder needs to prefetch and unpack that data.

For that reason the rest of the file consists of variable-size repeat of data chunks for each stream prefixed with 32-bit size. Chunks may be empty.

Data streams are:

  • stream 0 - opcodes
  • stream 1 - X offsets
  • stream 2 - Y offsets
  • stream 3 - colour data

Frame decoding works in the following way:

 pal_present = read_stream(OPCODES, 1);
 if (pal_present) {
  pal = read_stream(CLR, 1024); // in RGBA format
 }
 for each line {
   pos = 0;
   while (pos < width) {
     op = read_stream(OPCODES, 1);
     switch (op) {
     case 0: // long copy
       len = (uint16_t)read_stream(OPCODES, 2);
       copy len pixels to the current line position from CLR stream
       pos += len;
       break;
     case 0x01..0x7F: // short copy
       len = op;
       copy len pixels to the current line position from CLR stream
       pos += len;
       break;
     case 0x80: // end of line
       pos = width;
       break;
     case 0x81: // long copy of previous segment
       len = (uint16_t)read_stream(OPCODES, 2);
       xoff = (uint16_t)read_stream(XOFF, 2);
       yoff = read_stream(YOFF, 1) - 127;
       copy len pixels from (x, y + yoff) position in the previous frame
       pos += len;
       break;
     default: // short copy of previous segment
       len = op;
       xoff = (uint16_t)read_stream(XOFF, 2);
       yoff = read_stream(YOFF, 1) - 127;
       copy len pixels from (x, y + yoff) position in the previous frame
       pos += len;
     }
   }
 }