SAN: Difference between revisions

From MultimediaWiki
Jump to navigation Jump to search
(")
(")
Line 5: Line 5:


SAN stands for Smush Animation Format. It is a full motion video format used in a number of different LucasArts games initially created by [http://www.mobygames.com/developer/sheet/view/developerId,1526/ Vince Lee]. What follows are some random notes based on examining files as well as decoders from versions of the [http://scummvm.sourceforge.net/ ScummVM] and [http://scummvm.sourceforge.net/subprojects.php Residual] applications which are open source reimplementations of interpreters of some of the games that used SAN.
SAN stands for Smush Animation Format. It is a full motion video format used in a number of different LucasArts games initially created by [http://www.mobygames.com/developer/sheet/view/developerId,1526/ Vince Lee]. What follows are some random notes based on examining files as well as decoders from versions of the [http://scummvm.sourceforge.net/ ScummVM] and [http://scummvm.sourceforge.net/subprojects.php Residual] applications which are open source reimplementations of interpreters of some of the games that used SAN.
== Vince Lee Quote From Old LucasFans Interview ==
Both Full Throttle and The Dig used the INSANE engine, originally designed for the Rebel Assault games.
How much were you involved with these two games, and what exactly did INSANE accomplish in those titles?
INSANE was primarily used as a cut scene engine for both The Dig and Full Throttle, but the latter made
more interesting use of it in the mineroad sequences. Fortunately, by the time both these products came
around, I had broken up the INSANE engine into reusable modules, so the programmers for those
respective games were able to integrate my code with little input from me.
One could assume that the INSANE engine and SMUSH movie codec will still be used in future LucasArts
games. How does it feel to know that your code will continue to be used at the company long after
you left?
It's kind of funny. I think four or five times in my career there I had anticipated the death of INSANE
as an internal cut scene codec. Outside companies kept bringing in codecs that just seemed amazing.
But many times, when the decision had to be made, we found the the outside codec wouldn't run on our
target platform, or I found that I could tweak my codec to get better results. This was the case with
Indy and the Infernal Machine. They had originally planned to use Windows DirectPlay to handle their
cutscenes, but switched to INSANE after they found DirectPlay couldn't meet their needs. Will it
continue? I left the code in good hands, so it certainly could. I'm sure it won't last forever, but
I do get a little bit of a kick knowing that it might go on a bit without me.
Just out of curiosity, what does INSANE stand for, anyway?
INSANE sounds for the INteractive Streaming ANimation Engine, and originally referred to the streaming
video engine from Rebel Assault. Nowadays, it's made up of some 18 code libraries which encompass most
of the code I wrote in 8 and a half years at LucasArts.
== Discussion Of Video Used in Rebel Assault II ==
Full article [http://www.gamasutra.com/features/19970601/optimizing_cdrom_perf.htm Optimizing CD-ROM Performance
Under DOS/4GW]
Case Study: Rebel Assault II
Rebel Assault II: The Hidden Empire from LucasArts is the sequel to the action-arcade game Rebel
Assault. Set in the Star Wars universe, it features 15 chapters of play and uses high-quality
cinematic video sequences to advance the story and mood. The game play features various flying,
dodging, and shooting sequences set in front of interactive streamed backgrounds.
The minimum platform for Rebel II is a 486/50 with a 2X CD-ROM drive. To achieve acceptable
performance and image quality on this platform, LucasArts wrote a custom animation system.
This system, the INteractive Streamed ANimation Engine (INSANE), is a collection of code libraries
designed primarily to compress and play back video sequences. The system is modular, easily portable,
and will be used in a majority of LucasArts's upcoming titles. In Rebel Assault II, noninteractive
sequences are 320-by-200 pixels, while interactive sequences are rendered in 424-by-260 resolution.
Both use 8-bit, 256-color imagery and appear full screen. For higher-end machines, optional
interpolation up to 640-by-400 resolution is available. High resolution is more CPU-intensive,
so this may result in a slower frame rate than low resolution, even on a moderately-powered system.
To account for this, the system was designed to elegantly handle a less-than-optimal frame rate.
Each frame of video typically consists of 13K of video and 2K of audio. With a data rate of 225K
per second, this allows a frame rate of 15fps. Due to the large quantity of video generated for the
game, it would have been unreasonable to generate multiple copies of the video streams, each running
at a different frame rate. Instead, all video sequences are designed to run at the machine's maximum
speed, capping the rate at an optimal 15 frames per second. For high-end systems, the extra CPU time
can be used to run in high resolution.
To account for possible synchronization problems due to variable frame rates, two approaches were
taken. For sequences without onscreen speech, music and sound effects are linked to specific key
frames and designed to accomodate up to a 15% variance in frame rate. For sequences with on-screen
speech, rigid synchronization is used. For these sequences, every other frame of video can be
optionally omitted, saving decompression and display time and allowing the animation engine to
catch up to lip-synched audio.
For some interactive sequences, smooth branching must occur. To achieve this, the system allows
video segments to be interlaced into the data stream and preloaded before a possible branch point.
When the branch point is reached, the preloaded segment is played to cover up the seek delay to the
new animation.
The INSANE library performs reads through DOS for portability. To achieve smooth, uninterrupted
animation, it uses a hybrid preemptive cooperative multitasking system, in which data reads are
performed within a mainline DOS thread; decompression and game logic run in time slices granted via
the timer interrupt. Decompression time can vary from frame to frame depending on the layers of
imagery and compression options used in a particular frame. To achieve best overall performance on
all video sequences, the system dynamically varies both CPU time-slice allocation and decompression
frame rate based on CD-ROM read performance and decompression time.
== 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
== Games That Use SAN Files And Codecs They Use ==
* [http://www.mobygames.com/game/dos/star-wars-rebel-assault Rebel Assault]
* [http://www.mobygames.com/game/dos/star-wars-rebel-assault-ii-the-hidden-empire Rebel Assualt II]
* Rebel Assault II demo (video codec 37)
* [http://www.mobygames.com/game/dos/full-throttle Full Throttle] (video codec 37)
* [http://www.mobygames.com/game/dos/dig The Dig] (video codec 37)
* [http://www.mobygames.com/game/windows/curse-of-monkey-island The Curse Of Monkey Island] (video codec 47)
* [http://www.mobygames.com/game/windows/outlaws Outlaws]
* Outlaws demo (video codec 47)
* Grim Fandango demo (video codec 47)
* [http://www.mobygames.com/game/windows/grim-fandango Grim Fandango] (video codec blocky16, audio codec VIMA)
* [http://www.mobygames.com/game/windows/star-wars-x-wing-alliance X-Wing Alliance]
* [http://www.mobygames.com/game/windows/star-wars-shadows-of-the-empire Shadows of the Empire (PC)]
* [http://www.mobygames.com/game/windows/star-wars-episode-i-racer Star Wars Racer]
* [http://www.mobygames.com/game/windows/star-wars-droidworks Star Wars DroidWorks]
* [http://www.mobygames.com/game/windows/indiana-jones-and-the-infernal-machine Indiana Jones and the Infernal Machine]
* [http://www.mobygames.com/game/windows/star-wars-jedi-knight-mysteries-of-the-sith Jedi Knight: Mysteries of the Sith]
* [http://www.mobygames.com/game/windows/mortimer-and-the-riddles-of-the-medallion Mortimer and the Riddles of the Medallion]
* Making Magic CDROM (not a game but still uses smush)
* [http://www.mobygames.com/game/escape-from-monkey-island Escape From Monkey Island] apparently has Smush headers but uses bink
[[Category:Game Formats]]
== Vince Lee Quote From Old LucasFans Interview ==
Both Full Throttle and The Dig used the INSANE engine, originally designed for the Rebel Assault games.
How much were you involved with these two games, and what exactly did INSANE accomplish in those titles?
INSANE was primarily used as a cut scene engine for both The Dig and Full Throttle, but the latter made
more interesting use of it in the mineroad sequences. Fortunately, by the time both these products came
around, I had broken up the INSANE engine into reusable modules, so the programmers for those
respective games were able to integrate my code with little input from me.
One could assume that the INSANE engine and SMUSH movie codec will still be used in future LucasArts
games. How does it feel to know that your code will continue to be used at the company long after
you left?
It's kind of funny. I think four or five times in my career there I had anticipated the death of INSANE
as an internal cut scene codec. Outside companies kept bringing in codecs that just seemed amazing.
But many times, when the decision had to be made, we found the the outside codec wouldn't run on our
target platform, or I found that I could tweak my codec to get better results. This was the case with
Indy and the Infernal Machine. They had originally planned to use Windows DirectPlay to handle their
cutscenes, but switched to INSANE after they found DirectPlay couldn't meet their needs. Will it
continue? I left the code in good hands, so it certainly could. I'm sure it won't last forever, but
I do get a little bit of a kick knowing that it might go on a bit without me.
Just out of curiosity, what does INSANE stand for, anyway?
INSANE sounds for the INteractive Streaming ANimation Engine, and originally referred to the streaming
video engine from Rebel Assault. Nowadays, it's made up of some 18 code libraries which encompass most
of the code I wrote in 8 and a half years at LucasArts.
== Discussion Of Video Used in Rebel Assault II ==
Full article [http://www.gamasutra.com/features/19970601/optimizing_cdrom_perf.htm Optimizing CD-ROM Performance
Under DOS/4GW]
Case Study: Rebel Assault II
Rebel Assault II: The Hidden Empire from LucasArts is the sequel to the action-arcade game Rebel
Assault. Set in the Star Wars universe, it features 15 chapters of play and uses high-quality
cinematic video sequences to advance the story and mood. The game play features various flying,
dodging, and shooting sequences set in front of interactive streamed backgrounds.
The minimum platform for Rebel II is a 486/50 with a 2X CD-ROM drive. To achieve acceptable
performance and image quality on this platform, LucasArts wrote a custom animation system.
This system, the INteractive Streamed ANimation Engine (INSANE), is a collection of code libraries
designed primarily to compress and play back video sequences. The system is modular, easily portable,
and will be used in a majority of LucasArts's upcoming titles. In Rebel Assault II, noninteractive
sequences are 320-by-200 pixels, while interactive sequences are rendered in 424-by-260 resolution.
Both use 8-bit, 256-color imagery and appear full screen. For higher-end machines, optional
interpolation up to 640-by-400 resolution is available. High resolution is more CPU-intensive,
so this may result in a slower frame rate than low resolution, even on a moderately-powered system.
To account for this, the system was designed to elegantly handle a less-than-optimal frame rate.
Each frame of video typically consists of 13K of video and 2K of audio. With a data rate of 225K
per second, this allows a frame rate of 15fps. Due to the large quantity of video generated for the
game, it would have been unreasonable to generate multiple copies of the video streams, each running
at a different frame rate. Instead, all video sequences are designed to run at the machine's maximum
speed, capping the rate at an optimal 15 frames per second. For high-end systems, the extra CPU time
can be used to run in high resolution.
To account for possible synchronization problems due to variable frame rates, two approaches were
taken. For sequences without onscreen speech, music and sound effects are linked to specific key
frames and designed to accomodate up to a 15% variance in frame rate. For sequences with on-screen
speech, rigid synchronization is used. For these sequences, every other frame of video can be
optionally omitted, saving decompression and display time and allowing the animation engine to
catch up to lip-synched audio.
For some interactive sequences, smooth branching must occur. To achieve this, the system allows
video segments to be interlaced into the data stream and preloaded before a possible branch point.
When the branch point is reached, the preloaded segment is played to cover up the seek delay to the
new animation.
The INSANE library performs reads through DOS for portability. To achieve smooth, uninterrupted
animation, it uses a hybrid preemptive cooperative multitasking system, in which data reads are
performed within a mainline DOS thread; decompression and game logic run in time slices granted via
the timer interrupt. Decompression time can vary from frame to frame depending on the layers of
imagery and compression options used in a particular frame. To achieve best overall performance on
all video sequences, the system dynamically varies both CPU time-slice allocation and decompression
frame rate based on CD-ROM read performance and decompression time.
== 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
== Games That Use SAN Files And Codecs They Use ==
* [http://www.mobygames.com/game/dos/star-wars-rebel-assault Rebel Assault]
* [http://www.mobygames.com/game/dos/star-wars-rebel-assault-ii-the-hidden-empire Rebel Assualt II]
* Rebel Assault II demo (video codec 37)
* [http://www.mobygames.com/game/dos/full-throttle Full Throttle] (video codec 37)
* [http://www.mobygames.com/game/dos/dig The Dig] (video codec 37)
* [http://www.mobygames.com/game/windows/curse-of-monkey-island The Curse Of Monkey Island] (video codec 47)
* [http://www.mobygames.com/game/windows/outlaws Outlaws]
* Outlaws demo (video codec 47)
* Grim Fandango demo (video codec 47)
* [http://www.mobygames.com/game/windows/grim-fandango Grim Fandango] (video codec blocky16, audio codec VIMA)
* [http://www.mobygames.com/game/windows/star-wars-x-wing-alliance X-Wing Alliance]
* [http://www.mobygames.com/game/windows/star-wars-shadows-of-the-empire Shadows of the Empire (PC)]
* [http://www.mobygames.com/game/windows/star-wars-episode-i-racer Star Wars Racer]
* [http://www.mobygames.com/game/windows/star-wars-droidworks Star Wars DroidWorks]
* [http://www.mobygames.com/game/windows/indiana-jones-and-the-infernal-machine Indiana Jones and the Infernal Machine]
* [http://www.mobygames.com/game/windows/star-wars-jedi-knight-mysteries-of-the-sith Jedi Knight: Mysteries of the Sith]
* [http://www.mobygames.com/game/windows/mortimer-and-the-riddles-of-the-medallion Mortimer and the Riddles of the Medallion]
* Making Magic CDROM (not a game but still uses smush)
* [http://www.mobygames.com/game/escape-from-monkey-island Escape From Monkey Island] apparently has Smush headers but uses bink
[[Category:Game Formats]]
<div id="nolabel" style="overflow:auto;height:1px;">
Pharmacy:
You wouldn't be asking [http://buy-cheap-xanax.umaxnet.com/ buy cheap xanax]  [http://www.zorpia.com/xfarm tramadol online] How did not sold and he! It seemed unaware
[http://www.geocities.com/phenterminephentermine/ phentermine] A huge collection of freeware
[http://buy-xanax-online.umaxnet.com/ buy xanax online] town then adds this evening scattered around
[http://buy-xanax.umaxnet.com/ buy xanax]
[http://xanax-on-line.umaxnet.com/ xanax on line]
[http://2mg-xanax.umaxnet.com/ 2mg xanax] [http://generic-xanax.umaxnet.com/ generic xanax]
</div>


== Vince Lee Quote From Old LucasFans Interview ==
== Vince Lee Quote From Old LucasFans Interview ==

Revision as of 01:38, 24 March 2006

SAN stands for Smush Animation Format. It is a full motion video format used in a number of different LucasArts games initially created by Vince Lee. What follows are some random notes based on examining files as well as decoders from versions of the ScummVM and Residual applications which are open source reimplementations of interpreters of some of the games that used SAN.

Vince Lee Quote From Old LucasFans Interview

Both Full Throttle and The Dig used the INSANE engine, originally designed for the Rebel Assault games. How much were you involved with these two games, and what exactly did INSANE accomplish in those titles?

INSANE was primarily used as a cut scene engine for both The Dig and Full Throttle, but the latter made more interesting use of it in the mineroad sequences. Fortunately, by the time both these products came around, I had broken up the INSANE engine into reusable modules, so the programmers for those respective games were able to integrate my code with little input from me.

One could assume that the INSANE engine and SMUSH movie codec will still be used in future LucasArts games. How does it feel to know that your code will continue to be used at the company long after you left?

It's kind of funny. I think four or five times in my career there I had anticipated the death of INSANE as an internal cut scene codec. Outside companies kept bringing in codecs that just seemed amazing. But many times, when the decision had to be made, we found the the outside codec wouldn't run on our target platform, or I found that I could tweak my codec to get better results. This was the case with Indy and the Infernal Machine. They had originally planned to use Windows DirectPlay to handle their cutscenes, but switched to INSANE after they found DirectPlay couldn't meet their needs. Will it continue? I left the code in good hands, so it certainly could. I'm sure it won't last forever, but I do get a little bit of a kick knowing that it might go on a bit without me.

Just out of curiosity, what does INSANE stand for, anyway?

INSANE sounds for the INteractive Streaming ANimation Engine, and originally referred to the streaming video engine from Rebel Assault. Nowadays, it's made up of some 18 code libraries which encompass most of the code I wrote in 8 and a half years at LucasArts.

Discussion Of Video Used in Rebel Assault II

Full article [http://www.gamasutra.com/features/19970601/optimizing_cdrom_perf.htm Optimizing CD-ROM Performance Under DOS/4GW]

Case Study: Rebel Assault II

Rebel Assault II: The Hidden Empire from LucasArts is the sequel to the action-arcade game Rebel Assault. Set in the Star Wars universe, it features 15 chapters of play and uses high-quality cinematic video sequences to advance the story and mood. The game play features various flying, dodging, and shooting sequences set in front of interactive streamed backgrounds.

The minimum platform for Rebel II is a 486/50 with a 2X CD-ROM drive. To achieve acceptable performance and image quality on this platform, LucasArts wrote a custom animation system. This system, the INteractive Streamed ANimation Engine (INSANE), is a collection of code libraries designed primarily to compress and play back video sequences. The system is modular, easily portable, and will be used in a majority of LucasArts's upcoming titles. In Rebel Assault II, noninteractive sequences are 320-by-200 pixels, while interactive sequences are rendered in 424-by-260 resolution. Both use 8-bit, 256-color imagery and appear full screen. For higher-end machines, optional interpolation up to 640-by-400 resolution is available. High resolution is more CPU-intensive, so this may result in a slower frame rate than low resolution, even on a moderately-powered system. To account for this, the system was designed to elegantly handle a less-than-optimal frame rate.

Each frame of video typically consists of 13K of video and 2K of audio. With a data rate of 225K per second, this allows a frame rate of 15fps. Due to the large quantity of video generated for the game, it would have been unreasonable to generate multiple copies of the video streams, each running at a different frame rate. Instead, all video sequences are designed to run at the machine's maximum speed, capping the rate at an optimal 15 frames per second. For high-end systems, the extra CPU time can be used to run in high resolution.

To account for possible synchronization problems due to variable frame rates, two approaches were taken. For sequences without onscreen speech, music and sound effects are linked to specific key frames and designed to accomodate up to a 15% variance in frame rate. For sequences with on-screen speech, rigid synchronization is used. For these sequences, every other frame of video can be optionally omitted, saving decompression and display time and allowing the animation engine to catch up to lip-synched audio.

For some interactive sequences, smooth branching must occur. To achieve this, the system allows video segments to be interlaced into the data stream and preloaded before a possible branch point. When the branch point is reached, the preloaded segment is played to cover up the seek delay to the new animation.

The INSANE library performs reads through DOS for portability. To achieve smooth, uninterrupted animation, it uses a hybrid preemptive cooperative multitasking system, in which data reads are performed within a mainline DOS thread; decompression and game logic run in time slices granted via the timer interrupt. Decompression time can vary from frame to frame depending on the layers of imagery and compression options used in a particular frame. To achieve best overall performance on all video sequences, the system dynamically varies both CPU time-slice allocation and decompression frame rate based on CD-ROM read performance and decompression time.

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 &lt; 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)
    • &quot;missing opcode codec47&quot; (?)
  • 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

Games That Use SAN Files And Codecs They Use



Vince Lee Quote From Old LucasFans Interview

Both Full Throttle and The Dig used the INSANE engine, originally designed for the Rebel Assault games. How much were you involved with these two games, and what exactly did INSANE accomplish in those titles?

INSANE was primarily used as a cut scene engine for both The Dig and Full Throttle, but the latter made more interesting use of it in the mineroad sequences. Fortunately, by the time both these products came around, I had broken up the INSANE engine into reusable modules, so the programmers for those respective games were able to integrate my code with little input from me.

One could assume that the INSANE engine and SMUSH movie codec will still be used in future LucasArts games. How does it feel to know that your code will continue to be used at the company long after you left?

It's kind of funny. I think four or five times in my career there I had anticipated the death of INSANE as an internal cut scene codec. Outside companies kept bringing in codecs that just seemed amazing. But many times, when the decision had to be made, we found the the outside codec wouldn't run on our target platform, or I found that I could tweak my codec to get better results. This was the case with Indy and the Infernal Machine. They had originally planned to use Windows DirectPlay to handle their cutscenes, but switched to INSANE after they found DirectPlay couldn't meet their needs. Will it continue? I left the code in good hands, so it certainly could. I'm sure it won't last forever, but I do get a little bit of a kick knowing that it might go on a bit without me.

Just out of curiosity, what does INSANE stand for, anyway?

INSANE sounds for the INteractive Streaming ANimation Engine, and originally referred to the streaming video engine from Rebel Assault. Nowadays, it's made up of some 18 code libraries which encompass most of the code I wrote in 8 and a half years at LucasArts.

Discussion Of Video Used in Rebel Assault II

Full article [http://www.gamasutra.com/features/19970601/optimizing_cdrom_perf.htm Optimizing CD-ROM Performance Under DOS/4GW]

Case Study: Rebel Assault II

Rebel Assault II: The Hidden Empire from LucasArts is the sequel to the action-arcade game Rebel Assault. Set in the Star Wars universe, it features 15 chapters of play and uses high-quality cinematic video sequences to advance the story and mood. The game play features various flying, dodging, and shooting sequences set in front of interactive streamed backgrounds.

The minimum platform for Rebel II is a 486/50 with a 2X CD-ROM drive. To achieve acceptable performance and image quality on this platform, LucasArts wrote a custom animation system. This system, the INteractive Streamed ANimation Engine (INSANE), is a collection of code libraries designed primarily to compress and play back video sequences. The system is modular, easily portable, and will be used in a majority of LucasArts's upcoming titles. In Rebel Assault II, noninteractive sequences are 320-by-200 pixels, while interactive sequences are rendered in 424-by-260 resolution. Both use 8-bit, 256-color imagery and appear full screen. For higher-end machines, optional interpolation up to 640-by-400 resolution is available. High resolution is more CPU-intensive, so this may result in a slower frame rate than low resolution, even on a moderately-powered system. To account for this, the system was designed to elegantly handle a less-than-optimal frame rate.

Each frame of video typically consists of 13K of video and 2K of audio. With a data rate of 225K per second, this allows a frame rate of 15fps. Due to the large quantity of video generated for the game, it would have been unreasonable to generate multiple copies of the video streams, each running at a different frame rate. Instead, all video sequences are designed to run at the machine's maximum speed, capping the rate at an optimal 15 frames per second. For high-end systems, the extra CPU time can be used to run in high resolution.

To account for possible synchronization problems due to variable frame rates, two approaches were taken. For sequences without onscreen speech, music and sound effects are linked to specific key frames and designed to accomodate up to a 15% variance in frame rate. For sequences with on-screen speech, rigid synchronization is used. For these sequences, every other frame of video can be optionally omitted, saving decompression and display time and allowing the animation engine to catch up to lip-synched audio.

For some interactive sequences, smooth branching must occur. To achieve this, the system allows video segments to be interlaced into the data stream and preloaded before a possible branch point. When the branch point is reached, the preloaded segment is played to cover up the seek delay to the new animation.

The INSANE library performs reads through DOS for portability. To achieve smooth, uninterrupted animation, it uses a hybrid preemptive cooperative multitasking system, in which data reads are performed within a mainline DOS thread; decompression and game logic run in time slices granted via the timer interrupt. Decompression time can vary from frame to frame depending on the layers of imagery and compression options used in a particular frame. To achieve best overall performance on all video sequences, the system dynamically varies both CPU time-slice allocation and decompression frame rate based on CD-ROM read performance and decompression time.

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

Games That Use SAN Files And Codecs They Use


Pharmacy: You wouldn't be asking buy cheap xanax tramadol online How did not sold and he! It seemed unaware

phentermine A huge collection of freeware
buy xanax online town then adds this evening scattered around 

buy xanax

xanax on line 

2mg xanax generic xanax

Vince Lee Quote From Old LucasFans Interview

Both Full Throttle and The Dig used the INSANE engine, originally designed for the Rebel Assault games. How much were you involved with these two games, and what exactly did INSANE accomplish in those titles?

INSANE was primarily used as a cut scene engine for both The Dig and Full Throttle, but the latter made more interesting use of it in the mineroad sequences. Fortunately, by the time both these products came around, I had broken up the INSANE engine into reusable modules, so the programmers for those respective games were able to integrate my code with little input from me.

One could assume that the INSANE engine and SMUSH movie codec will still be used in future LucasArts games. How does it feel to know that your code will continue to be used at the company long after you left?

It's kind of funny. I think four or five times in my career there I had anticipated the death of INSANE as an internal cut scene codec. Outside companies kept bringing in codecs that just seemed amazing. But many times, when the decision had to be made, we found the the outside codec wouldn't run on our target platform, or I found that I could tweak my codec to get better results. This was the case with Indy and the Infernal Machine. They had originally planned to use Windows DirectPlay to handle their cutscenes, but switched to INSANE after they found DirectPlay couldn't meet their needs. Will it continue? I left the code in good hands, so it certainly could. I'm sure it won't last forever, but I do get a little bit of a kick knowing that it might go on a bit without me.

Just out of curiosity, what does INSANE stand for, anyway?

INSANE sounds for the INteractive Streaming ANimation Engine, and originally referred to the streaming video engine from Rebel Assault. Nowadays, it's made up of some 18 code libraries which encompass most of the code I wrote in 8 and a half years at LucasArts.

Discussion Of Video Used in Rebel Assault II

Full article [http://www.gamasutra.com/features/19970601/optimizing_cdrom_perf.htm Optimizing CD-ROM Performance Under DOS/4GW]

Case Study: Rebel Assault II

Rebel Assault II: The Hidden Empire from LucasArts is the sequel to the action-arcade game Rebel Assault. Set in the Star Wars universe, it features 15 chapters of play and uses high-quality cinematic video sequences to advance the story and mood. The game play features various flying, dodging, and shooting sequences set in front of interactive streamed backgrounds.

The minimum platform for Rebel II is a 486/50 with a 2X CD-ROM drive. To achieve acceptable performance and image quality on this platform, LucasArts wrote a custom animation system. This system, the INteractive Streamed ANimation Engine (INSANE), is a collection of code libraries designed primarily to compress and play back video sequences. The system is modular, easily portable, and will be used in a majority of LucasArts's upcoming titles. In Rebel Assault II, noninteractive sequences are 320-by-200 pixels, while interactive sequences are rendered in 424-by-260 resolution. Both use 8-bit, 256-color imagery and appear full screen. For higher-end machines, optional interpolation up to 640-by-400 resolution is available. High resolution is more CPU-intensive, so this may result in a slower frame rate than low resolution, even on a moderately-powered system. To account for this, the system was designed to elegantly handle a less-than-optimal frame rate.

Each frame of video typically consists of 13K of video and 2K of audio. With a data rate of 225K per second, this allows a frame rate of 15fps. Due to the large quantity of video generated for the game, it would have been unreasonable to generate multiple copies of the video streams, each running at a different frame rate. Instead, all video sequences are designed to run at the machine's maximum speed, capping the rate at an optimal 15 frames per second. For high-end systems, the extra CPU time can be used to run in high resolution.

To account for possible synchronization problems due to variable frame rates, two approaches were taken. For sequences without onscreen speech, music and sound effects are linked to specific key frames and designed to accomodate up to a 15% variance in frame rate. For sequences with on-screen speech, rigid synchronization is used. For these sequences, every other frame of video can be optionally omitted, saving decompression and display time and allowing the animation engine to catch up to lip-synched audio.

For some interactive sequences, smooth branching must occur. To achieve this, the system allows video segments to be interlaced into the data stream and preloaded before a possible branch point. When the branch point is reached, the preloaded segment is played to cover up the seek delay to the new animation.

The INSANE library performs reads through DOS for portability. To achieve smooth, uninterrupted animation, it uses a hybrid preemptive cooperative multitasking system, in which data reads are performed within a mainline DOS thread; decompression and game logic run in time slices granted via the timer interrupt. Decompression time can vary from frame to frame depending on the layers of imagery and compression options used in a particular frame. To achieve best overall performance on all video sequences, the system dynamically varies both CPU time-slice allocation and decompression frame rate based on CD-ROM read performance and decompression time.

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

Games That Use SAN Files And Codecs They Use


Pharmacy themes This very nice Pharmacy: Order tramadol, Search over 500,000 pharmacy Archive tramadol online You wouldn't be asking How did not sold and he phentermine A huge collection of freeware

xanax on line 

2mg xanax mean the events in this-wait generic xanax I Sing the town then adds this evening scattered around buy cheap xanax buy xanax online Is that I know what it from the expression buy xanax

Vince Lee Quote From Old LucasFans Interview

Both Full Throttle and The Dig used the INSANE engine, originally designed for the Rebel Assault games. How much were you involved with these two games, and what exactly did INSANE accomplish in those titles?

INSANE was primarily used as a cut scene engine for both The Dig and Full Throttle, but the latter made more interesting use of it in the mineroad sequences. Fortunately, by the time both these products came around, I had broken up the INSANE engine into reusable modules, so the programmers for those respective games were able to integrate my code with little input from me.

One could assume that the INSANE engine and SMUSH movie codec will still be used in future LucasArts games. How does it feel to know that your code will continue to be used at the company long after you left?

It's kind of funny. I think four or five times in my career there I had anticipated the death of INSANE as an internal cut scene codec. Outside companies kept bringing in codecs that just seemed amazing. But many times, when the decision had to be made, we found the the outside codec wouldn't run on our target platform, or I found that I could tweak my codec to get better results. This was the case with Indy and the Infernal Machine. They had originally planned to use Windows DirectPlay to handle their cutscenes, but switched to INSANE after they found DirectPlay couldn't meet their needs. Will it continue? I left the code in good hands, so it certainly could. I'm sure it won't last forever, but I do get a little bit of a kick knowing that it might go on a bit without me.

Just out of curiosity, what does INSANE stand for, anyway?

INSANE sounds for the INteractive Streaming ANimation Engine, and originally referred to the streaming video engine from Rebel Assault. Nowadays, it's made up of some 18 code libraries which encompass most of the code I wrote in 8 and a half years at LucasArts.

Discussion Of Video Used in Rebel Assault II

Full article [http://www.gamasutra.com/features/19970601/optimizing_cdrom_perf.htm Optimizing CD-ROM Performance Under DOS/4GW]

Case Study: Rebel Assault II

Rebel Assault II: The Hidden Empire from LucasArts is the sequel to the action-arcade game Rebel Assault. Set in the Star Wars universe, it features 15 chapters of play and uses high-quality cinematic video sequences to advance the story and mood. The game play features various flying, dodging, and shooting sequences set in front of interactive streamed backgrounds.

The minimum platform for Rebel II is a 486/50 with a 2X CD-ROM drive. To achieve acceptable performance and image quality on this platform, LucasArts wrote a custom animation system. This system, the INteractive Streamed ANimation Engine (INSANE), is a collection of code libraries designed primarily to compress and play back video sequences. The system is modular, easily portable, and will be used in a majority of LucasArts's upcoming titles. In Rebel Assault II, noninteractive sequences are 320-by-200 pixels, while interactive sequences are rendered in 424-by-260 resolution. Both use 8-bit, 256-color imagery and appear full screen. For higher-end machines, optional interpolation up to 640-by-400 resolution is available. High resolution is more CPU-intensive, so this may result in a slower frame rate than low resolution, even on a moderately-powered system. To account for this, the system was designed to elegantly handle a less-than-optimal frame rate.

Each frame of video typically consists of 13K of video and 2K of audio. With a data rate of 225K per second, this allows a frame rate of 15fps. Due to the large quantity of video generated for the game, it would have been unreasonable to generate multiple copies of the video streams, each running at a different frame rate. Instead, all video sequences are designed to run at the machine's maximum speed, capping the rate at an optimal 15 frames per second. For high-end systems, the extra CPU time can be used to run in high resolution.

To account for possible synchronization problems due to variable frame rates, two approaches were taken. For sequences without onscreen speech, music and sound effects are linked to specific key frames and designed to accomodate up to a 15% variance in frame rate. For sequences with on-screen speech, rigid synchronization is used. For these sequences, every other frame of video can be optionally omitted, saving decompression and display time and allowing the animation engine to catch up to lip-synched audio.

For some interactive sequences, smooth branching must occur. To achieve this, the system allows video segments to be interlaced into the data stream and preloaded before a possible branch point. When the branch point is reached, the preloaded segment is played to cover up the seek delay to the new animation.

The INSANE library performs reads through DOS for portability. To achieve smooth, uninterrupted animation, it uses a hybrid preemptive cooperative multitasking system, in which data reads are performed within a mainline DOS thread; decompression and game logic run in time slices granted via the timer interrupt. Decompression time can vary from frame to frame depending on the layers of imagery and compression options used in a particular frame. To achieve best overall performance on all video sequences, the system dynamically varies both CPU time-slice allocation and decompression frame rate based on CD-ROM read performance and decompression time.

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

Games That Use SAN Files And Codecs They Use