ARC
ARC files are archives that store information about files and directories, and are used to organize assets within the games. While the file extension is .arc, the FourCC for the format is RARC. Following other observed naming conventions, the addition of R to the beginning of the FourCC suggests that the format was refactored at some point from an earlier version.
ARC is used in nearly every first-party Nintendo game in the GameCube era, including The Wind Waker and Twilight Princess. Luigi's Mansion typically used YAY0-compressed archives with the extension .szp, and Super Mario Sunshine used YAZ0-compressed archives with the extension .szs.
Contents
File Format
Note that all multi-byte values described below are in big-endian format.
Header
This contains data about the archive itself, such as the total size of the file and the counts and offsets of the nodes and file entries. It is 0x40/64 bytes long and has the following structure:
Offset | Size | Name | Description |
---|---|---|---|
|
|
FourCC | The file type, the four characters 'RARC' |
|
|
File Size | The size of the entire ARC file |
|
|
Unknown Constant | Always 0x20/32. Same as the amount subtracted from the offsets in this header, possibly indicating a header size. |
|
|
File Data Offset | The offset to the file data |
|
|
File Data Size 1 | The size of the block of file data |
|
|
File Data Size 2 | Duplicate of File Data Size 1? |
|
|
Padding | Pads the header to 0x1C/28 bytes |
|
|
Padding | Pads the header to 0x20/32 bytes |
|
|
Node Count | The number of Nodes in the archive |
|
|
Node Offset | The offset to the start of the Node data |
|
|
File Entry Count | The number of File Entries in the archive |
|
|
File Entry Offset | The offset of the File Entry data |
|
|
String Table Length | The length of the String Table |
|
|
String Table Offset | The offset of the String Table |
|
|
File Entry Count | Seems to be the number of File Entries stored as a 2-byte value |
|
|
Unknown Byte 1 | Unknown, always 1? |
|
|
Unknown Byte 2 | Unknown, padding for the previous byte? |
|
|
Padding | Pads the header to 0x40/64 bytes |
All of the offsets in this file need 0x20 added to them to reflect their actual offset within the file. This is the same value as the constant at offset 0x08. This could possibly mean that the first 0x20 bytes of this header are the "main" header, or otherwise ignored for offset counting in a way the next 0x20 bytes are not.
Node
Nodes represent the directories stored within the archive. They are 0x10/16 bytes long, and are laid out like this:
Offset | Size | Name | Description |
---|---|---|---|
|
|
Type | Typically the file type contained in this archive (BMD, BDL, STB, etc) |
|
|
Name Offset | The offset to the directory's actual name |
|
|
Name Hash | A hash of the directory's name. See "Filename Hashing Algorithm" below |
|
|
File Entry Count | The number of file entries that belong to this directory |
|
|
First File Entry Index | The index of the first file entry that belongs to this directory |
File Entry
These entries represent the actual hierarchy of files and directories. They are 0x14/20 bytes long and have the following structure:
Offset | Size | Name | Description |
---|---|---|---|
|
|
File ID | This is 0xFFFF if the entry represents a directory. Otherwise, the game uses this ID to load specific files |
|
|
Name Hash | A hash of the file or directory's name. See "Filename Hashing Algorithm" below |
|
|
Type | An indicator of whether this entry is a file or a directory |
|
|
Padding | A byte of padding to round out the Type byte above |
|
|
Name Offset | The offset of this entry's name in the string table |
|
|
Data Offset | If this is a directory, the is the index of the directory's node. If it's a file, it's the offset to the file's data. |
|
|
Data Size | If this is a directory, the is the size of a directory node, 0x10/16. If it's a file, it's the size of the file's data. |
|
|
Padding | Four bytes of padding to round out the entry to 0x14/20 bytes long. |
Every directory contains two extra file entries in addition to the entries that represent the actual files it contains. These two file entries have the names "." and "..", and may stem from how Unix-like systems and Windows handle directories. In those cases, "." represents a link to the current directory, and ".." represents a link to the current directory's parent.
String Table
The string table is simply a series of null-terminated strings.
Filename Hashing Algorithm
Nodes and File Entries have a field for a hash of their names. An example function for creating this hash from the name string is found below. It uses C# syntax.
private ushort HashName(string name) { short hash = 0; short multiplier = 1; if (name.Length + 1 == 2) { multiplier = 2; } if (name.Length + 1 >= 3) { multiplier = 3; } foreach (char c in name) { hash = (short)(hash * multiplier); hash += (short)c; } return (ushort)hash; }
See Also
WAarchive Tools, a tool and library written by LordNed and Sage_of_Mirrors for extracting and packing ARC files