Super Street Fighter II TURBO Movie Format
Jump to navigation
Jump to search
Super Street Fighter II TURBO Movie Format
| Format type | Image |
|---|---|
| Hardware | VGA |
| Colour depth | 8-bit (VGA) |
| Minimum size (pixels) | 320x200 |
| Maximum size (pixels) | 320x200 |
| Palette | Internal |
| Plane count | 1 |
| Transparent pixels? | No |
| Hitmap pixels? | No |
| Games |
This format is used by Super Street Fighter II TURBO to store intro movies.
General
Each .FMV file is compressed with Rob Northern Compression, then with RLE Compression of delta frames.
Algorithm
using System.Drawing;
namespace SuperStreetFighter2Turbo;
public sealed class Fmv
{
public Fmv(Stream stream)
{
Reader = new BinaryReader(stream);
if (Reader.ReadInt32() != 0x564D4641)
{
throw new InvalidDataException();
}
FrameCount = Reader.ReadUInt16();
Frame.AsSpan().Fill(Reader.ReadByte());
for (var i = 0; i < Palette.Length; i++)
{
var r = Expand(Reader.ReadByte());
var g = Expand(Reader.ReadByte());
var b = Expand(Reader.ReadByte());
Palette[i] = Color.FromArgb(r, g, b);
}
Reader.ReadByte();
return;
static byte Expand(byte b)
{
return (byte)((b * 255 + 31) / 63);
}
}
public byte[] Frame { get; } = new byte[320 * 200];
private int FrameCount { get; }
private int FrameIndex { get; set; }
public Color[] Palette { get; } = new Color[256];
private BinaryReader Reader { get; }
public bool Read()
{
if (FrameIndex >= FrameCount)
{
return false;
}
FrameIndex++;
var index = 0;
while (true)
{
var flags = Reader.ReadByte();
if ((flags & 0xC0) == 0xC0)
{
return true;
}
var count = 4 * (flags & 0x3F);
var chunk = Frame.AsSpan(index, count);
switch (flags & 0xC0)
{
case 0x40:
{
chunk.Fill(Reader.ReadByte());
break;
}
case 0x80:
{
Reader.ReadExactly(chunk);
break;
}
}
index += count;
}
}
}
Credits
aybe on the 17th of May 2026
