SAN: Difference between revisions

From MultimediaWiki
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 based on LucasArts' SCUMM engine. What follows are some random notes based on examining files as well as older versions of the [http://scummvm.sourceforge.net/ ScummVM] application.
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

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

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