SAN: Difference between revisions
Jump to navigation
Jump to search
No edit summary |
(quite a few non SCUMM games use Smush) |
||
Line 1: | Line 1: | ||
* Company: [[LucasArts]] | * Company: [[LucasArts]] | ||
SAN stands for Smush Animation Format. It is a full motion video format used in a number of different games | SAN stands for Smush Animation Format. It is a full motion video format used in a number of different LucasArts games. What follows are some random notes based on examining files as well as older versions of the [http://scummvm.sourceforge.net/ ScummVM] application. | ||
== File Format == | == File Format == |
Revision as of 16:33, 17 February 2006
- Company: LucasArts
SAN stands for Smush Animation Format. It is a full motion video format used in a number of different LucasArts games. What follows are some random notes based on examining files as well as older versions of the ScummVM application.
File Format
- a chunked multimedia format possibly with several variations
- multi-byte numbers are little endian (always?)
- no: the chunk lengths are big endian
- chunks are marked by FOURCCs; known FOURCCs:
- ANIM
- AHDR
- FRME
- NPAL
- FOBJ
- PSAD
- TRES
- XPAL
- LACT
- STOR
- FTCH
- SKIP
- STRK
- SMRK
- SHDR
- SDAT
- SAUD
- iMUS
- FRMT
- TEXT
- REGN
- STOP
- MAP_
- DATA
- ETRS
- carries a payload comprised of different chunk types
- these chunk types are known:
- codec 1
- codec 37
- codec 44
- codec 47
Codec 1: RLE Encoding
- for each line in image height:
- 16-bit number indicates encoded line size
- while there are still encoded data bytes for this line:
- next byte is code
- length = code / 2 + 1
- if bit 0 of code is set:
- value = next byte
- if value is 0:
- skip (length) pixels in output
- else:
- put (value) in output (length) times
- else:
- for each count in length:
- value = next byte
- if value is 0:
- skip pixel in output
- else:
- put value in output
- for each count in length:
Codec 37
- assign width and height
- assign bw as block width
- assign bh as block height
- codec must operate on 4x4 blocks
- assign pitch as block width * 4 (not the same as width necessarily since block width is rounded up to nearest multiple of 4)
- assign chunk size as size of input chunk - 14
- allocate a buffer with that size
- read chunk_size bytes into new buffer
- sequence number LE_16 @ chunk[2]
- decoded size is LE_32 @ chunk[4]
- maskflags = chunk[12]
- make table with pitch and chunk_buffer[1] as index:
- index *= 255
- if (index + 254 < sizeof(table) / 2)
- assert error condition
- for i = 0..255
- j = (i + index) * 2
- offsettable[i] = maketable_bytes[j+1] * pitch + maketable_bytes[j]
- if (chunk[0] == 0)
- else if (chunk[0] == 1)
- "missing opcode codec47" (?)
- else if (chunk[0] == 2)
- ...
- else if (chunk[0] == 3)
- ...
- else if (chunk[0] == 4)
- ...
Codec 44
- iterate through the encoded chunk from 0 to size - 14 (?):
- size of encoded line = next LE_16 in chunk
- while size is not 0:
- count = next byte
- pixel = next byte
- put (pixel) in output (count) times
- if size of line is not 0 at this point:
- count = next LE_16 + 1
- copy (count) pixels from encoded stream to output
- at the end of line, output buffer rewinds by one pixel (?)
Codec 47
- chunk size = size of chunk passed in minus 14 bytes
- sequence number = first LE_16 of chunk
- encoded graphic data begins at chunk + 26
- the bytes at chunk[12] and chunk[13] serve as initializers for deltabufs[0] and [1] respectively