Super Street Fighter II TURBO Sprite Format

From ModdingWiki
Jump to navigation Jump to search
Super Street Fighter II TURBO Sprite Format
Super Street Fighter II TURBO Sprite Format.png
Format typeImage
HardwareVGA
Colour depth8-bit (VGA)
Minimum size (pixels)Unknown
Maximum size (pixels)Unknown
PaletteExternal
Plane count1
Transparent pixels?Yes
Hitmap pixels?Yes
Games

This format is used by Super Street Fighter II TURBO to store sprite graphics.

General

Most of the files are RNC-compressed and therefore should be decompressed beforehand.

Some files may store multiple frames each one after the other, this, without any indication.

The associated external VGA Palette may have the same file name, or not if it's a generic one.

Sprites used during Continue presumably are XOR-ed as some regions have diverging indices.

Algorithm

! Figure out why it does work for all files but LEVELS\DHALSIM\ANIMS.SPR.

The format is a simple form of RLE Compression.

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Text;

namespace SSF2T
{
    public class Sprite
    {
        public Sprite(Stream stream)
        {
            if (stream == null)
                throw new ArgumentNullException(nameof(stream));

            using var reader = new BinaryReader(stream, Encoding.Default, true);

            Width = reader.ReadUInt16();
            Height = reader.ReadUInt16();

            var pixels = new byte[Width * Height];

            var index = 0;

            for (var i = 0; i < Height; i++)
            {
                while (true)
                {
                    var b = reader.ReadByte();

                    if (b == 0)
                    {
                        break;
                    }

                    if (b < 128)
                    {
                        index += b;
                        continue;
                    }

                    for (var j = 0; j < b - 128; j++)
                    {
                        pixels[index++] = reader.ReadByte();
                    }
                }
            }

            Pixels = new ReadOnlyCollection<byte>(pixels);
        }

        public ushort Width { get; }

        public ushort Height { get; }

        public IReadOnlyList<byte> Pixels { get; }

    }
}

Credits

Reverse-engineered by aybe on 9th of August 2021.