Difference between revisions of "Palette file"

From Worms Knowledge Base

Jump to: navigation, search
 
m (Corrected BinaryReader variable name in load code)
 
(15 intermediate revisions by 6 users not shown)
Line 1: Line 1:
W:A uses the Microsoft [[w:RIFF|RIFF]] file format. You can find some specs on it [http://www.saettler.com/RIFFMCI/riffmci.html|here].
+
{{ParentArticle|[[File formats]]}}
 +
W:A and WWP use the Microsoft [[w:Resource_Interchange_File_Format|RIFF file format]] to store their color palettes used in the frontend. The palette files all reside in the "Graphics" directory and its subfolders.
 +
 
 +
== File format ==
 +
 
 +
As like every other RIFF file, the PAL files start off with the RIFF header:
 +
* 4-byte RIFF signature "RIFF"
 +
* 4-byte file length in bytes (excluding the RIFF header)
 +
* 4-byte PAL signature "PAL " (note the space / 0x20 at the end)
 +
 
 +
The PAL files then include 4 different chunks, of which only the "data" chunk is important. The other chunks "offl", "tran" and "unde" are all 32 bytes long, filled with 0x00. Their purpose remains unknown since they can be deleted and the game still accepts the PAL files.
 +
Like other RIFF chunks, the data chunk starts with its signature and length:
 +
* 4-byte data chunk signature "data"
 +
* 4-byte data chunk size excluding the chunk header
 +
* 2-byte PAL version. This version is always 0x0300.
 +
* 2-byte color entry count. This determines how many colors are following.
 +
 
 +
Each color consists of 4 bytes holding the following data:
 +
* 1-byte red amount of color
 +
* 1-byte green amount of color
 +
* 1-byte blue amount of color
 +
* 1-byte "flags" - W:A PAL files always have the 0x00 flag, so no flag is set.
 +
 
 +
== Example code ==
 +
 
 +
The following C# example code can be used to load PAL files:
 +
 
 +
public static List<Color> LoadPal(string filename)
 +
{
 +
    List<Color> colors = new List<Color>();
 +
    FileStream stream = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read);
 +
    using (BinaryReader br = new BinaryReader(stream))
 +
    {
 +
        // RIFF header
 +
        string riff = ReadByteString(br, 4); // "RIFF"
 +
        int dataSize = br.ReadInt32();
 +
        string type = ReadByteString(br, 4); // "PAL "
 +
 +
        // Data chunk
 +
        string chunkType = ReadByteString(br, 4); // "data"
 +
        int chunkSize = br.ReadInt32();
 +
        short palVersion = br.ReadInt16(); // always 0x0300
 +
        short palEntries = br.ReadInt16();
 +
 +
        // Colors
 +
        for (int i = 0; i < palEntries; i++)
 +
        {
 +
            byte red = br.ReadByte();
 +
            byte green = br.ReadByte();
 +
            byte blue = br.ReadByte();
 +
            byte flags = br.ReadByte(); // always 0x00
 +
            colors.Add(Color.FromArgb(red, green, blue));
 +
        }
 +
    }
 +
    return colors;
 +
}
 +
 +
private static string ReadByteString(BinaryReader br, int length)
 +
{
 +
    return ASCIIEncoding.GetString(br.ReadBytes(length));
 +
}
 +
 
 +
This C# example code can be used to save PAL files:
 +
 
 +
public static void SavePal(string filename, List<Color> colors)
 +
{
 +
    // Calculate file length
 +
    int length = 4 + 4 + 4 + 4 + 2 + 2 + colors.Count * 4;
 +
   
 +
    FileStream stream = new FileStream(filename, FileMode.Create, FileAccess.Write, FileShare.None);
 +
    using (BinaryWriter bw = new BinaryWriter(stream))
 +
    {
 +
        // RIFF header
 +
        WriteStringBytes(bw, "RIFF");
 +
        bw.Write(length);
 +
        WriteStringBytes(bw, "PAL ");
 +
       
 +
        // Data chunk
 +
        WriteStringBytes(bw, "data");
 +
        bw.Write(colors.Count * 4 + 4);
 +
        bw.Write(0x0300); // PAL version
 +
        bw.Write((short)colors.Count);
 +
       
 +
        // Colors
 +
        foreach (Color color in colors)
 +
        {
 +
            bw.Write((byte)color.R);
 +
            bw.Write((byte)color.G);
 +
            bw.Write((byte)color.B);
 +
            bw.Write((byte)0); // Flag in W:A always 0x00
 +
        }
 +
    }
 +
}
 +
 +
private static void WriteStringBytes(BinaryWriter bw, string value)
 +
{
 +
    bw.Write(ASCIIEncoding.GetBytes(value));
 +
}
 +
 
 +
== See also ==
 +
* [[Worms PAL Editor]] - does not save the 3 useless chunks, with no side-effect in the game
 +
 
 +
== External links ==
 +
* [[w:Resource_Interchange_File_Format|RIFF File Format]] on Wikipedia
 +
* [http://www.warpspeed.com.au/cgi-bin/inf2html.cmd?..\html\book\Toolkt40\MMREF3.INF+2264 RIFF PAL file format description]

Latest revision as of 11:19, 10 August 2012

(Up to File formats)

W:A and WWP use the Microsoft RIFF file format to store their color palettes used in the frontend. The palette files all reside in the "Graphics" directory and its subfolders.

File format

As like every other RIFF file, the PAL files start off with the RIFF header:

  • 4-byte RIFF signature "RIFF"
  • 4-byte file length in bytes (excluding the RIFF header)
  • 4-byte PAL signature "PAL " (note the space / 0x20 at the end)

The PAL files then include 4 different chunks, of which only the "data" chunk is important. The other chunks "offl", "tran" and "unde" are all 32 bytes long, filled with 0x00. Their purpose remains unknown since they can be deleted and the game still accepts the PAL files. Like other RIFF chunks, the data chunk starts with its signature and length:

  • 4-byte data chunk signature "data"
  • 4-byte data chunk size excluding the chunk header
  • 2-byte PAL version. This version is always 0x0300.
  • 2-byte color entry count. This determines how many colors are following.

Each color consists of 4 bytes holding the following data:

  • 1-byte red amount of color
  • 1-byte green amount of color
  • 1-byte blue amount of color
  • 1-byte "flags" - W:A PAL files always have the 0x00 flag, so no flag is set.

Example code

The following C# example code can be used to load PAL files:

public static List<Color> LoadPal(string filename)
{
    List<Color> colors = new List<Color>();
    FileStream stream = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read);
    using (BinaryReader br = new BinaryReader(stream))
    {
        // RIFF header
        string riff = ReadByteString(br, 4); // "RIFF"
        int dataSize = br.ReadInt32();
        string type = ReadByteString(br, 4); // "PAL "

        // Data chunk
        string chunkType = ReadByteString(br, 4); // "data"
        int chunkSize = br.ReadInt32();
        short palVersion = br.ReadInt16(); // always 0x0300
        short palEntries = br.ReadInt16();

        // Colors
        for (int i = 0; i < palEntries; i++)
        {
            byte red = br.ReadByte();
            byte green = br.ReadByte();
            byte blue = br.ReadByte();
            byte flags = br.ReadByte(); // always 0x00
            colors.Add(Color.FromArgb(red, green, blue));
        }
    }
    return colors;
}

private static string ReadByteString(BinaryReader br, int length)
{
    return ASCIIEncoding.GetString(br.ReadBytes(length));
}

This C# example code can be used to save PAL files:

public static void SavePal(string filename, List<Color> colors)
{
    // Calculate file length
    int length = 4 + 4 + 4 + 4 + 2 + 2 + colors.Count * 4;
    
    FileStream stream = new FileStream(filename, FileMode.Create, FileAccess.Write, FileShare.None);
    using (BinaryWriter bw = new BinaryWriter(stream))
    {
        // RIFF header
        WriteStringBytes(bw, "RIFF");
        bw.Write(length);
        WriteStringBytes(bw, "PAL ");
        
        // Data chunk
        WriteStringBytes(bw, "data");
        bw.Write(colors.Count * 4 + 4);
        bw.Write(0x0300); // PAL version
        bw.Write((short)colors.Count);
        
        // Colors
        foreach (Color color in colors)
        {
            bw.Write((byte)color.R);
            bw.Write((byte)color.G);
            bw.Write((byte)color.B);
            bw.Write((byte)0); // Flag in W:A always 0x00
        }
    }
}

private static void WriteStringBytes(BinaryWriter bw, string value)
{
    bw.Write(ASCIIEncoding.GetBytes(value));
}

See also

  • Worms PAL Editor - does not save the 3 useless chunks, with no side-effect in the game

External links

Personal tools