UBB
- Extension: ubb , sometimes hnm
- Company: CRYO Interactive Entertainment
- Samples: ADD ME
UBB2 is another generation of FMV format developed by Cryo. It is an improved version of HNM4 format. While general container format remains the same, video encoding is slightly improved.
File Format
Remains the same as was used in HNM4. Following parts has changed:
- File signature is "UBB2" now.
- Video chunk has "IV" TwoCC.
Video Compression
The video frame is encoded in a series of horizontal colums of variable width and height. However, columns height (and some of their coding properties) may only change at the beginning of new line.
Encoded stream consist of column copy mode bytes:
bits: 7 - swap rows/columns 6 - vertical reverse 5 - horizontal reverse 4..0 - column width index (table lookup, see below)
Each of such code generally means "copy a width-by-height column from some other place to the current, using flags provided."
Flags behavior can be illustrated as follows (assuming 2x3 block and the source points to 'M' pixel):
Source Normal Horizontal Vertical Swap ABCDE MN ML MN MR FGHIJ RS RQ HI NS KLMNO -> WX WV CD OT PQRST UVWXY
Multiple flags can be used together.
Encoded column width depends on column's height:
2: 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,18,20,22,24,26,28,30,32,34,36,38,40,44,48,52,56 3: 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,22,24,26,28,30,32,34,36,38,40,42,44 4: 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,28,30,32,34,36,38
Source column offset may be an "absolute" offset - byte distance from the current column, or relative X:Y offset.
- For absolute offset read next 2-byte value (unsigned, little-endian) and add base oofset.
- For relative offset read next byte, extract X and Y deltas from it and add base deltas.
Certain combination used for special purposes. Those are:
- 0x20 - skip: read next byte (width) and copy width+1 column from previous frame
- 0x60 - solo: draw 1-pixel wide column using next bytes of input
- 0xA0 - draw: read next byte (width) and draw width+2 column using next bytes of input (top-down, left-right)
- 0xE0 - mode: examine next byte.
- if byte is zero, then read two bytes (width, color) and fill width+1 column with color.
- if byte is non-zero, change the decoding properties as follows:
+------+--------+--------+--------+----------+---------+--------+ | byte | height | source | offset | Y.X bits | X-base | Y-base | +------+--------+--------+--------+----------+---------+--------+ | 1 | end of decoding | +------+--------+--------+--------+----------+---------+--------+ | 2 | 2 | prev | -32768 | N/A | N/A | N/A | | 3 | 3 | prev | -32768 | N/A | N/A | N/A | | 4 | 4 | prev | -32768 | N/A | N/A | N/A | | 5 | 2 | prev | N/A | 4.4 | -8 | -8 | | 6 | 3 | prev | N/A | 4.4 | -8 | -8 | | 7 | 4 | prev | N/A | 4.4 | -8 | -8 | +------+--------+--------+--------+----------+---------+--------+ | 8 | 2 | prev | N/A | 4.4 | -2 | -8 | | 9 | 2 | prev | N/A | 4.4 | -14 | -8 | | 10 | 2 | prev | N/A | 4.4 | -8 | -2 | | 11 | 2 | prev | N/A | 4.4 | -8 | -14 | | 12 | 2 | prev | N/A | 4.4 | -2 | -2 | | 13 | 2 | prev | N/A | 4.4 | -14 | -2 | | 14 | 2 | prev | N/A | 4.4 | -2 | -14 | | 15 | 2 | prev | N/A | 4.4 | -14 | -14 | +------+--------+--------+--------+----------+---------+--------+ | 16 | 3 | prev | N/A | 4.4 | -2 | -8 | | 17 | 3 | prev | N/A | 4.4 | -14 | -8 | | 18 | 3 | prev | N/A | 4.4 | -8 | -2 | | 19 | 3 | prev | N/A | 4.4 | -8 | -14 | | 20 | 3 | prev | N/A | 4.4 | -2 | -2 | | 21 | 3 | prev | N/A | 4.4 | -14 | -2 | | 22 | 3 | prev | N/A | 4.4 | -2 | -14 | | 23 | 3 | prev | N/A | 4.4 | -14 | -14 | +------+--------+--------+--------+----------+---------+--------+ | 24 | 4 | prev | N/A | 4.4 | -2 | -8 | | 25 | 4 | prev | N/A | 4.4 | -14 | -8 | | 26 | 4 | prev | N/A | 4.4 | -8 | -2 | | 27 | 4 | prev | N/A | 4.4 | -8 | -14 | | 28 | 4 | prev | N/A | 4.4 | -2 | -2 | | 29 | 4 | prev | N/A | 4.4 | -14 | -2 | | 30 | 4 | prev | N/A | 4.4 | -2 | -14 | | 31 | 4 | prev | N/A | 4.4 | -14 | -14 | +------+--------+--------+--------+----------+---------+--------+ | 32 | 2 | curr | -65536 | N/A | N/A | N/A | | 33 | 2 | curr | N/A | 3.5 | -16 | -8 | | 34 | 2 | curr | N/A | 4.4 | -8 | -16 | | 35 | 2 | curr | N/A | 4.4 | -24 | -16 | | 36 | 2 | curr | N/A | 4.4 | +8 | -16 | | 37 | 2 | curr | N/A | 5.3 | -4 | -32 | | 38 | 2 | curr | N/A | 5.3 | -12 | -32 | | 39 | 2 | curr | N/A | 5.3 | +4 | -32 | +------+--------+--------+--------+----------+---------+--------+ | 40 | 3 | curr | -65536 | N/A | N/A | N/A | | 41 | 3 | curr | N/A | 3.5 | -16 | -8 | | 42 | 3 | curr | N/A | 4.4 | -8 | -16 | | 43 | 3 | curr | N/A | 4.4 | -24 | -16 | | 44 | 3 | curr | N/A | 4.4 | +8 | -16 | | 45 | 3 | curr | N/A | 5.3 | -4 | -32 | | 46 | 3 | curr | N/A | 5.3 | -12 | -32 | | 47 | 3 | curr | N/A | 5.3 | +4 | -32 | +------+--------+--------+--------+----------+---------+--------+
- prev means source is the previous frame, curr - current
- Y.X means "Y" value in upper Y bits of byte, "X" in lower X bits.
Trivia
Apparently this format has another less-used name - HNM5.
Games Using UBB
- Megarace II
- lots of others