RARC (File Format)

From Wexos's Wiki
Jump to navigationJump to search

RARC files are archive files used in some Wii and GameCube games, such as Super Mario Galaxy and Super Mario Galaxy 2. The directories are always stored inside a root directory.

File Format

Header

The file starts with a header that is 0x20 bytes long:

Offset Type Description
0x00 Char[4] File magic. Always RARC in ASCII.
0x04 UInt32 Length of this file in bytes.
0x08 UInt32 Length of this header in bytes. Always 0x20.
0x0C UInt32 Offset to file data. Relative to the end of this header.
0x10 UInt32 Total size of all file data.
0x14 UInt32 Size of file data which is preloaded into MRAM.
0x18 UInt32 Size of file data which is preloaded into ARAM.
0x1C Byte[4] Padding.

Info Block

Directly after the header comes the info block. It is a 0x20 bytes structure as follows:

Offset Type Description
0x00 UInt32 Number of directories.
0x04 UInt32 Offset to the first directory. Relative to the start of this block.
0x08 UInt32 Total number of nodes.
0x0C UInt32 Offset to the first node. Relative to the start of this block.
0x10 UInt32 Length of the whole string table.
0x14 UInt32 Offset to string table. Relative to the start of this block.
0x18 UInt16 Next available node ID.
0x1A UInt16 1 indicates that the node ID of each node equals the index of the node.
0x1C Byte[4] Padding.

Directory

A directory represents a folder. All files contains a root directory which links to all other files and folders. Each directory is a 0x10 bytes structure.

Offset Type Description
0x00 Char[4] Some kind of identifier. The root has ROOT, other nodes have their first 4 characters of the name in upper case. If the length of the node's name is less than 4, then the rest of this string is padded with spaces.
0x04 UInt32 Name offset. Relative to the start of the string table.
0x08 UInt16 Hash of the directory name.
0x0A UInt16 Number of nodes in this folder.
0x0C UInt32 First node index. This is the index of the first node that is part of this folder.

Node

A node can either be a file or a folder. If it's a folder, then it refers to a directory. Otherwise it links to file data. Each entry is a 0x14 bytes structure.

Offset Type Description
0x00 UInt16 Node ID.
0x02 UInt16 Hash of the node name.
0x04 Byte Bit flag that specifies the node type and what this node contains. This is usually 0x02 for folders and 0x11 for files.
ABCD xEFG:
  • A: Sets the compression type, if the file is compressed. 0 = Yay0, 1 = Yaz0.
  • B: 1 indicates that the file data should be loaded from the DVD whenever it's needed.
  • C: 1 indicates that the file data should be preloaded into ARAM.
  • D: 1 indicates that the file data should be preloaded into MRAM.
  • E: 1 indicates that the file is compressed.
  • F: 1 indicates that this node is a folder. If it is a folder, node index and all compression flags are ignored.
  • G: 1 indicates that this node is a file.
0x05 UInt24 Offset to a string into the string table. Relative to the start of the string table.
0x08 UInt32 File: Offset to file data, relative to the start of the file data.

Folder: Index of the directory that represents this folder.

0x0C UInt32 File: Length of the file data in bytes.

Folder: Unknown, always 0x10.

0x10 UInt32 Unknown.

Special Nodes

There are two special folder nodes presented at the end of each folder, included in the count in the directory owner. The first one is ".", and it links to current directory. The second one is ".." and links to the parent directory.

String Table

The string table consist of null-terminated strings. The offset and length of this string table is stored in the info block.

Hash

In all directory and node. there is a hash of the name stored. To calculate the hash you need to loop through each character. Start with the hash as 0. For each character you multiply the hash by 3 and then add the character's value to the hash. The algorithm is demonstrated using the following C# code:

public static ushort CalculateHash(string Name)
{
  ushort Hash = 0;

  for (int i = 0; i < Name.Length; i++)
  {
    Hash *= 3;
    Hash += Name[i];
  }

  return Hash;
}

Tools

The following tools can handle RARC files: