SGA: Difference between revisions

From MultimediaWiki
Jump to navigation Jump to search
(These edits reflect the results of extensive analysis of several SGA files using a decoder program of my own design.)
Line 32: Line 32:


== Chunk Types ==
== Chunk Types ==
Some observed chunk types are:
Some known chunk types are:


* 0x81: compressed video (Night Trap 32x uses this)
* 0x81: encoded video (used in most 32X games by Digital Pictures)
* 0xC1: uncompressed video (used in Night Trap and Make My Video: INXS but with 3 palettes)
* 0xC6: compressed video
* 0xC7: compressed video
* 0xC8: compressed video (used in Sewer Shark)
* 0xCD: video, perhaps followed by audio
* 0xCB: video, perhaps in files that are video only
* 0xA1: audio, sign/magnitude 8-bit PCM
* 0xA1: audio, sign/magnitude 8-bit PCM
* 0xE7: compressed video (Used in Make My Video: INXS)
* 0xB4: compressed? video (used in Prize Fighter "ALLOPTS.SGA", among others)
* 0xE8: compressed video (Used in Ground Zero Texas)
* 0xC1: uncompressed video (used in Night Trap SCD, Sewer Shark, Corpse Killer SCD, and others)
* 0xC2: compressed? video (used in Corpse Killer SCD)
* 0xC6: compressed video (used in Night Trap SCD "DPLOGO.SGA", Sewer Shark, Make My Video C&C, and others)
* 0xC7: compressed video (used in Prize Fighter and others)
* 0xC8: compressed video (used in Sewer Shark, Make My VIdeo C&C, and others)
* 0xCD: compressed? video (used in Double Switch SCD)
* 0xCB: compressed video (used in Prize Fighter, Double Switch "DPLOGO.SGA", Corpse Killer 32X)
* 0xCD: compressed video (used in Double Switch)
* 0xD1: compressed? overlay video (used in Sewer Shark when killing a Ratigator(TM, etc)
* 0xD4: compressed? overlay video (used in Corpse Killer SCD/32X for the zombies)
* 0xE7: compressed? video (Used in Make My Video C&C and INXS)
* 0xE8: compressed? video (Used in Ground Zero Texas)
 
== Encoded Video 0x81 ==
This type of video is probably most appropriately called "encoded" rather than "compressed". Video frames of this type are represented with a series of codes that indicate the size, color, and pixel layout of the graphics to be drawn, rather than, for example, LZSS encoded byte streams as in previous versions of SGA files.
 
The encoding scheme has been completely reverse-engineered, and a functional decoder has been written. A detailed description of the codes will be added at a later time.
 
== Audio 0x81 ==
Audio sample rate can be determined in the following way (for NTSC systems only?):
 
SamplesPerSecond = ((Byte 8 << 8) + Byte 9) * SEGA_CD_PCM_INCREMENT
SEGA_CD_PCM_INCREMENT is ~15.8945723, and is calculated as SEGA_CD_PCM_FREQUENCY_MAX / 2048
SEGA_CD_PCM_FREQUENCY_MAX is ~32552.084, and is calculated as SEGA_CD_CPU_FREQUENCY / 384
SEGA_CD_CPU_FREQUENCY is 12500000, and is calculated as SEGA_CD_CRYSTAL_FREQUENCY / 4
SEGA_CD_CRYSTAL_FREQUENCY is 50000000
 
The sample rate can also be used to determine the frame rate of video by using the formula SamplesPerSecond / NumSamples, where NumSamples is the length of the audio data in the audio chunk.


== Uncompressed Video 0xC1 ==
== Uncompressed Video 0xC1 ==

Revision as of 09:00, 23 June 2014

SGA is a multimedia file format commonly used for games on the Sega CD console system. Early versions of the format store uncompressed video frames. Newer versions use a simple LZ compression scheme. The final version of the format, used on Sega 32X/CD games use a yet to be determined compression method.

File Format

All multi-byte numbers in a SGA file are big-endian.

Due to using CD storage each chunk is stored using 2048 byte sectors. The first sector in the file contains 2048 bytes of data, each subsequent sectors contain a 2 byte header specifying how much of the chunk is left followed by 2046 bytes of data. One item to be aware of is if the value of the header is zero then to skip the next 2046 bytes and check the next header. (I'm presuming this has something to do with padding the CD for faster loading?)

An SGA file does not contain a global header, but has headers for each chunk. Each chunk can contain video or audio. Chunks are word aligned. Chunk header is 12-bytes

byte 0     chunk type 
byte 1     Stream
bytes 2-3  payload length 
bytes 4-7  time indicator
 non 32x
  byte 8     column start (can be ignored since we are not drawing on a 320x224 screen) 
  byte 9     row start (again can be ignored)
 32x
  byte 8     palette start (usually 1)
  byte 9     palette update size (0 if use existing palette)
byte 10    column size
byte 11    row size
bytes 12.. chunk payload

Bytes 4-5 are presumed to be part of the chunk preamble since the payload length specifies the length of the chunk.

When reading an audio chunk, bytes 8 and 9 represent the frequency counter value of the audio (For the PCM chip on the Sega CD). Bytes 11 and 12 are unknown (Usually 0x01 and 0x00 in Sewer Shark).

Chunk Types

Some known chunk types are:

  • 0x81: encoded video (used in most 32X games by Digital Pictures)
  • 0xA1: audio, sign/magnitude 8-bit PCM
  • 0xB4: compressed? video (used in Prize Fighter "ALLOPTS.SGA", among others)
  • 0xC1: uncompressed video (used in Night Trap SCD, Sewer Shark, Corpse Killer SCD, and others)
  • 0xC2: compressed? video (used in Corpse Killer SCD)
  • 0xC6: compressed video (used in Night Trap SCD "DPLOGO.SGA", Sewer Shark, Make My Video C&C, and others)
  • 0xC7: compressed video (used in Prize Fighter and others)
  • 0xC8: compressed video (used in Sewer Shark, Make My VIdeo C&C, and others)
  • 0xCD: compressed? video (used in Double Switch SCD)
  • 0xCB: compressed video (used in Prize Fighter, Double Switch "DPLOGO.SGA", Corpse Killer 32X)
  • 0xCD: compressed video (used in Double Switch)
  • 0xD1: compressed? overlay video (used in Sewer Shark when killing a Ratigator(TM, etc)
  • 0xD4: compressed? overlay video (used in Corpse Killer SCD/32X for the zombies)
  • 0xE7: compressed? video (Used in Make My Video C&C and INXS)
  • 0xE8: compressed? video (Used in Ground Zero Texas)

Encoded Video 0x81

This type of video is probably most appropriately called "encoded" rather than "compressed". Video frames of this type are represented with a series of codes that indicate the size, color, and pixel layout of the graphics to be drawn, rather than, for example, LZSS encoded byte streams as in previous versions of SGA files.

The encoding scheme has been completely reverse-engineered, and a functional decoder has been written. A detailed description of the codes will be added at a later time.

Audio 0x81

Audio sample rate can be determined in the following way (for NTSC systems only?):

SamplesPerSecond = ((Byte 8 << 8) + Byte 9) * SEGA_CD_PCM_INCREMENT SEGA_CD_PCM_INCREMENT is ~15.8945723, and is calculated as SEGA_CD_PCM_FREQUENCY_MAX / 2048 SEGA_CD_PCM_FREQUENCY_MAX is ~32552.084, and is calculated as SEGA_CD_CPU_FREQUENCY / 384 SEGA_CD_CPU_FREQUENCY is 12500000, and is calculated as SEGA_CD_CRYSTAL_FREQUENCY / 4 SEGA_CD_CRYSTAL_FREQUENCY is 50000000

The sample rate can also be used to determine the frame rate of video by using the formula SamplesPerSecond / NumSamples, where NumSamples is the length of the audio data in the audio chunk.

Uncompressed Video 0xC1

Genesis Video uses 4-bit(16 color) pixels and upto 4 palettes

Video is made up of tiles. (column * 4 * row * 8) (each byte has 2 pixels) Then palette data follows (if there is only 24 bytes then only one palette is used, otherwise there is 4 palettes) A palette map follows for videos that use 4 palettes.

Palette Data

Palettes are stored in an unusual format. As the genesis normally uses either RGB or BGR stored in nibbles (even though only the top 3 bits are used).

bitmap={1,2,4}

For bit=0 to 2
   for color=0 to 15
       red[color]+=Top Most Bit of Data *bitmap[bit]
   next
next

Repeat for green and blue.

Palette Map

Reading 2 bits for each tile, determines which of the 4 palettes to use.

For Row=0 to RowMax
   For Col=0 to ColMax
       PalMap[Row*ColMax+Col]=Top 2 Bits of data
   Next
Next

When Drawing the Tile you would select the palette based upon Map.

Compressed Video 0xC6, 0xC7, 0xC8

Chunks in this format consist of several 34 byte LZSS blocks. Each block contains a one word (2 bytes) tag of compression flags followed by 16 words of data.

The tag is read in bits, starting with the most significant (left most) bit. For each bit set to 0, there is an uncompressed word literal. For each bit set to 1, the following word is a displacement/length reference in the following format:

LLLD DDDD DDDD DDDD

L = Amount of words to copy (amount of bytes to copy * 2)
D = Displacement

This may be calculated as:

for count = 0 to top 3 bits of LZ word * 2
   data[current + count] = data[current + count - last 13 bits of LZ word]
next

Note that the displacement, unlike the copy amount, is based on bytes, not words. Also, the displacement does not have to be word aligned.

After the entire tag is read, the next flag block is read, and the process continues. The sequence ends when an reference word's top three bits are all zeros.

Games Using SGA