Difference between revisions of "Palette file"

From Worms Knowledge Base

Jump to: navigation, search
(Added C# example code for loading and saving)
m (Corrected BinaryReader variable name in load code)
 
(5 intermediate revisions by the same user not shown)
Line 1: Line 1:
 
{{ParentArticle|[[File formats]]}}
 
{{ParentArticle|[[File formats]]}}
W:A and WWP use the Microsoft [[w:RIFF|RIFF]] file format to store their color palettes used in the frontend. The palette files all reside in the "Graphics" directory and its subfolders.
+
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 ==
 
== File format ==
Line 9: Line 9:
 
* 4-byte PAL signature "PAL " (note the space / 0x20 at the end)
 
* 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 purpose of 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.
+
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:
 
Like other RIFF chunks, the data chunk starts with its signature and length:
 
* 4-byte data chunk signature "data"
 
* 4-byte data chunk signature "data"
Line 26: Line 26:
 
The following C# example code can be used to load PAL files:
 
The following C# example code can be used to load PAL files:
  
  public static void LoadPal(string filename)
+
  public static List<Color> LoadPal(string filename)
 
  {
 
  {
 
     List<Color> colors = new List<Color>();
 
     List<Color> colors = new List<Color>();
 
     FileStream stream = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read);
 
     FileStream stream = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read);
     using (BinaryReader reader = new BinaryReader(stream))
+
     using (BinaryReader br = new BinaryReader(stream))
 
     {
 
     {
         // RIFF Header
+
         // RIFF header
 
         string riff = ReadByteString(br, 4); // "RIFF"
 
         string riff = ReadByteString(br, 4); // "RIFF"
         int dataSize = reader.ReadInt32();
+
         int dataSize = br.ReadInt32();
 
         string type = ReadByteString(br, 4); // "PAL "
 
         string type = ReadByteString(br, 4); // "PAL "
 
   
 
   
         // Data Chunk
+
         // Data chunk
 
         string chunkType = ReadByteString(br, 4); // "data"
 
         string chunkType = ReadByteString(br, 4); // "data"
         int chunkSize = reader.ReadInt32();
+
         int chunkSize = br.ReadInt32();
         short palVersion = reader.ReadInt16(); // always 0x0300
+
         short palVersion = br.ReadInt16(); // always 0x0300
         short palEntries = reader.ReadInt16();
+
         short palEntries = br.ReadInt16();
 
   
 
   
 
         // Colors
 
         // Colors
 
         for (int i = 0; i < palEntries; i++)
 
         for (int i = 0; i < palEntries; i++)
 
         {
 
         {
             byte red = reader.ReadByte();
+
             byte red = br.ReadByte();
             byte green = reader.ReadByte();
+
             byte green = br.ReadByte();
             byte blue = reader.ReadByte();
+
             byte blue = br.ReadByte();
             byte flags = reader.ReadByte(); // always 0x00
+
             byte flags = br.ReadByte(); // always 0x00
 
             colors.Add(Color.FromArgb(red, green, blue));
 
             colors.Add(Color.FromArgb(red, green, blue));
 
         }
 
         }
 
     }
 
     }
 +
    return colors;
 
  }
 
  }
 
   
 
   
Line 62: Line 63:
 
This C# example code can be used to save PAL files:
 
This C# example code can be used to save PAL files:
  
  public void SavePal(string filename, List<Color> colors)
+
  public static void SavePal(string filename, List<Color> colors)
 
  {
 
  {
 
     // Calculate file length
 
     // Calculate file length
Line 70: Line 71:
 
     using (BinaryWriter bw = new BinaryWriter(stream))
 
     using (BinaryWriter bw = new BinaryWriter(stream))
 
     {
 
     {
         // RIFF Header
+
         // RIFF header
 
         WriteStringBytes(bw, "RIFF");
 
         WriteStringBytes(bw, "RIFF");
 
         bw.Write(length);
 
         bw.Write(length);
 
         WriteStringBytes(bw, "PAL ");
 
         WriteStringBytes(bw, "PAL ");
 
          
 
          
         // Data Chunk
+
         // Data chunk
 
         WriteStringBytes(bw, "data");
 
         WriteStringBytes(bw, "data");
 
         bw.Write(colors.Count * 4 + 4);
 
         bw.Write(colors.Count * 4 + 4);
Line 81: Line 82:
 
         bw.Write((short)colors.Count);
 
         bw.Write((short)colors.Count);
 
          
 
          
 +
        // Colors
 
         foreach (Color color in colors)
 
         foreach (Color color in colors)
 
         {
 
         {
Line 100: Line 102:
  
 
== External links ==
 
== External links ==
* [http://www.warpspeed.com.au/cgi-bin/inf2html.cmd?..\html\book\Toolkt40\MMREF3.INF+2264 RIFF file format description]
+
* [[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