Difference between revisions of "RARC (File Format)"
m |
m |
||
(16 intermediate revisions by 2 users not shown) | |||
Line 1: | Line 1: | ||
− | '''RARC''' files | + | '''RARC''' files are archive files used in some [[Wii]] and [[GameCube]] games, such as Super Mario Galaxy 1 & 2. The directories is always stored inside a root node. Compared to [[U8]], this root node is always named. |
+ | |||
= File Format = | = File Format = | ||
== Header == | == Header == | ||
Line 18: | Line 19: | ||
| 0x10 || UInt32 || Length of the '''file data'''. | | 0x10 || UInt32 || Length of the '''file data'''. | ||
|- | |- | ||
− | | 0x14 || UInt32 || Length of the '''file data''' again? Always the same as the previous value. | + | | 0x14 || UInt32 || {{Unknown-left|Length of the '''file data''' again? Always the same as the previous value.}} |
|- | |- | ||
− | | 0x18 || UInt32 || '''Unknown'''. | + | | 0x18 || UInt32 || {{Unknown-left|'''Unknown'''. Seems to always be 0.}} |
|- | |- | ||
− | | 0x1C || UInt32 || '''Unknown'''. | + | | 0x1C || UInt32 || {{Unknown-left|'''Unknown'''. Seems to always be 0.}} |
|} | |} | ||
== Info Block == | == Info Block == | ||
− | Directly after the header comes the info block. It is a 0x20 bytes structure: | + | Directly after the header comes the info block. It is a 0x20 bytes structure as follows: |
{| class="wikitable" | {| class="wikitable" | ||
Line 36: | Line 37: | ||
| 0x04 || UInt32 || '''Offset''' to the first [[#Node|node]]. Relative to the start of this block. | | 0x04 || UInt32 || '''Offset''' to the first [[#Node|node]]. Relative to the start of this block. | ||
|- | |- | ||
− | | 0x08 || UInt32 || | + | | 0x08 || UInt32 || The total number of '''[[#Directory|directories]] including all entries'''. |
|- | |- | ||
| 0x0C || UInt32 || '''Offset''' to the first directory. Relative to the start of this block. | | 0x0C || UInt32 || '''Offset''' to the first directory. Relative to the start of this block. | ||
Line 42: | Line 43: | ||
| 0x10 || UInt32 || Length of the whole [[#String Table|string table]]. | | 0x10 || UInt32 || Length of the whole [[#String Table|string table]]. | ||
|- | |- | ||
− | | 0x14 || UInt32 || '''Offset''' to [[#String Table|string table]]. | + | | 0x14 || UInt32 || '''Offset''' to [[#String Table|string table]]. Relative to the start of this block. |
|- | |- | ||
− | | 0x18 || UInt16 || | + | | 0x18 || UInt16 || The number of '''[[#Directory|directories]] that are files'''. |
|- | |- | ||
− | | 0x1A || UInt16 || '''Unknown'''. | + | | 0x1A || UInt16 || {{Unknown-left|'''Unknown'''. Seems to always be 0.}} |
|- | |- | ||
− | | 0x1C || UInt32 || '''Unknown'''. | + | | 0x1C || UInt32 || {{Unknown-left|'''Unknown'''. Seems to always be 0.}} |
|} | |} | ||
== Node == | == Node == | ||
− | A node | + | A node represents a folder. There is a root folder which links to other files and folders. Each node is a 0x10 bytes structure. |
{| class="wikitable" | {| class="wikitable" | ||
Line 58: | Line 59: | ||
! Offset !! Type !! Description | ! Offset !! Type !! Description | ||
|- | |- | ||
− | | 0x00 || String || Some kind of '''identifier'''. The root has ''ROOT'', other nodes have their first 4 characters of the name in upper case. | + | | 0x00 || String || 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 || '''Offset to a string''' into the [[#String Table|string table]]. Relative to the start of the [[#String Table|string table]]. | | 0x04 || UInt32 || '''Offset to a string''' into the [[#String Table|string table]]. Relative to the start of the [[#String Table|string table]]. | ||
|- | |- | ||
− | | 0x08 || UInt16 || | + | | 0x08 || UInt16 || '''[[#Hash|Hash]]''' of the string. |
|- | |- | ||
| 0x0A || UInt16 || '''Number of [[#Directory|directories]]''' in this folder. | | 0x0A || UInt16 || '''Number of [[#Directory|directories]]''' in this folder. | ||
|- | |- | ||
− | | 0x0C || UInt32 || The index of the [[#Directory|directory]]. | + | | 0x0C || UInt32 || The index of the first [[#Directory|directory]]. |
|} | |} | ||
== Directory == | == Directory == | ||
− | A directory can either be a file or a folder. If it's a folder, then it refers to a [[#Node|node]]. | + | A directory can either be a file or a folder. If it's a folder, then it refers to a [[#Node|node]]. Each entry is a 0x14 bytes structure. |
{| class="wikitable" | {| class="wikitable" | ||
Line 78: | Line 79: | ||
| 0x00 || UInt16 || '''Index of this directory'''. 0xFFFF if it's a folder. | | 0x00 || UInt16 || '''Index of this directory'''. 0xFFFF if it's a folder. | ||
|- | |- | ||
− | | 0x02 || UInt16 || | + | | 0x02 || UInt16 || '''[[#Hash|Hash]]''' of the string. |
|- | |- | ||
− | | 0x04 || UInt16 || | + | | 0x04 || UInt16 || {{Unknown-left|Type? Always 0x200 for folders and 0x1100 for files.}} |
|- | |- | ||
| 0x06 || UInt16 || '''Offset to a string''' into the [[#String Table|string table]]. Relative to the start of the [[#String Table|string table]]. | | 0x06 || UInt16 || '''Offset to a string''' into the [[#String Table|string table]]. Relative to the start of the [[#String Table|string table]]. | ||
Line 88: | Line 89: | ||
| 0x0C || UInt32 || '''Length of the file data''' in bytes. Unused if this is a folder. | | 0x0C || UInt32 || '''Length of the file data''' in bytes. Unused if this is a folder. | ||
|- | |- | ||
− | | 0x10 || UInt32 || '''Unknown'''. | + | | 0x10 || UInt32 || {{Unknown-left|'''Unknown'''. Seems to always be 0.}} |
|} | |} | ||
== String Table == | == String Table == | ||
The string table consist of null-termined strings. The offset and length of this string table is stored in the [[#Info Block|info block]]. | The string table consist of null-termined strings. The offset and length of this string table is stored in the [[#Info Block|info block]]. | ||
+ | |||
+ | == Hash == | ||
+ | In all [[#Directory|directory]] and [[#Node|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. | ||
+ | |||
+ | === C# Example === | ||
+ | <pre> | ||
+ | public static UInt16 CalculateHash(string Name) | ||
+ | { | ||
+ | UInt16 Hash = 0; | ||
+ | for (int i = 0; i < Name.Length; i++) | ||
+ | { | ||
+ | Hash *= 3; | ||
+ | Hash += Encoding.ASCII.GetBytes(new char[1] { Name[i] })[0]; | ||
+ | } | ||
+ | return Hash; | ||
+ | } | ||
+ | </pre> | ||
= Tools = | = Tools = | ||
The following tools can handle RARC files:<br> | The following tools can handle RARC files:<br> | ||
* [http://www.wiibrew.org/wiki/ARCTool ARCTool], by [http://www.wiibrew.org/wiki/User:Tpw_rules Tpw_rules] | * [http://www.wiibrew.org/wiki/ARCTool ARCTool], by [http://www.wiibrew.org/wiki/User:Tpw_rules Tpw_rules] | ||
− | * [http://florian.nouwt.com/wiki/index.php/Every_File_Explorer Every File Explorer], by | + | * [http://florian.nouwt.com/wiki/index.php/Every_File_Explorer Every File Explorer], by Gericom (not editable) |
* [[Wiimms SZS Tools]], by [[Wiimm]] | * [[Wiimms SZS Tools]], by [[Wiimm]] | ||
+ | * [[Wexos's Toolbox]], by [[Wexos]] | ||
− | [[Category:File Format]] | + | [[Category:File Format/Other]] |
Latest revision as of 09:51, 18 June 2021
RARC files are archive files used in some Wii and GameCube games, such as Super Mario Galaxy 1 & 2. The directories is always stored inside a root node. Compared to U8, this root node is always named.
File Format
Header
The file starts with a header that is 0x20 bytes long:
Offset | Type | Description |
---|---|---|
0x00 | String | File magic. Always RARC in ASCII. |
0x04 | UInt32 | Length of the file in bytes. |
0x08 | UInt32 | Length of this header in bytes. Always 0x20. |
0x0C | UInt32 | Offset to the file data. Relative to the end of this header. |
0x10 | UInt32 | Length of the file data. |
0x14 | UInt32 | Length of the file data again? Always the same as the previous value. |
0x18 | UInt32 | Unknown. Seems to always be 0. |
0x1C | UInt32 | Unknown. Seems to always be 0. |
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 nodes. |
0x04 | UInt32 | Offset to the first node. Relative to the start of this block. |
0x08 | UInt32 | The total number of directories including all entries. |
0x0C | UInt32 | Offset to the first directory. 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 | The number of directories that are files. |
0x1A | UInt16 | Unknown. Seems to always be 0. |
0x1C | UInt32 | Unknown. Seems to always be 0. |
Node
A node represents a folder. There is a root folder which links to other files and folders. Each node is a 0x10 bytes structure.
Offset | Type | Description |
---|---|---|
0x00 | String | 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 | Offset to a string into the string table. Relative to the start of the string table. |
0x08 | UInt16 | Hash of the string. |
0x0A | UInt16 | Number of directories in this folder. |
0x0C | UInt32 | The index of the first directory. |
Directory
A directory can either be a file or a folder. If it's a folder, then it refers to a node. Each entry is a 0x14 bytes structure.
Offset | Type | Description |
---|---|---|
0x00 | UInt16 | Index of this directory. 0xFFFF if it's a folder. |
0x02 | UInt16 | Hash of the string. |
0x04 | UInt16 | Type? Always 0x200 for folders and 0x1100 for files. |
0x06 | UInt16 | Offset to a string into the string table. Relative to the start of the string table. |
0x08 | UInt32 | File: Offset to file data. Folder: Index of the node that represente this folder. |
0x0C | UInt32 | Length of the file data in bytes. Unused if this is a folder. |
0x10 | UInt32 | Unknown. Seems to always be 0. |
String Table
The string table consist of null-termined 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.
C# Example
public static UInt16 CalculateHash(string Name) { UInt16 Hash = 0; for (int i = 0; i < Name.Length; i++) { Hash *= 3; Hash += Encoding.ASCII.GetBytes(new char[1] { Name[i] })[0]; } return Hash; }
Tools
The following tools can handle RARC files:
- ARCTool, by Tpw_rules
- Every File Explorer, by Gericom (not editable)
- Wiimms SZS Tools, by Wiimm
- Wexos's Toolbox, by Wexos