Difference between revisions of "RARC (File Format)"

From Custom Mario Kart
Jump to navigation Jump to search
m
m
 
(12 intermediate revisions by 2 users not shown)
Line 1: Line 1:
'''RARC''' files are archive files used in some [[Wii]] 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.
+
'''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 =
Line 19: 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 37: 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 || Number of [[#Directory|directories]].
+
| 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 45: Line 45:
 
| 0x14 || UInt32 || '''Offset''' to [[#String Table|string table]]. Relative to the start of this block.
 
| 0x14 || UInt32 || '''Offset''' to [[#String Table|string table]]. Relative to the start of this block.
 
|-
 
|-
| 0x18 || UInt16 || Number of [[#Directory|directories]] again?
+
| 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 represente a folder. There is a root folder which links to other files and folders. Each node is a 0x14 bytes structure:
+
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 59: 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 || Seems to be a hash of the name.
+
| 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.
Line 71: Line 71:
  
 
== 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 79: 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 || Seems to be a hash of the name.
+
| 0x02 || UInt16 || '''[[#Hash|Hash]]''' of the string.
 
|-
 
|-
| 0x04 || UInt16 || '''Unknown'''.
+
| 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 89: 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 [[Gericom]]
+
* [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: